Technical article
Build a multilingual website without SEO and maintenance problems
A multilingual website needs real translations and clear management. Learn how language URLs, hreflang, forms and a translation workflow fit together.
- Websites
- Build
- multilingual
- website
- SEO
- maintenance

In this article
Give each language its own reachable URL and canonical to that language version. Hreflang connects equivalent pages; it does not replace translation or justify canonicalising every language to Dutch.
Homepage example: /nl canonicalises to /nl, /en to /en and /fr to /fr. All three list the same reciprocal language alternatives. A language selector or suitable fallback may be x-default. Do not invent an alternate URL for a service without translated content.
- Open an explicit language URL with a different browser language and verify the choice is retained.
- Check HTTP status, self-canonical and reciprocal hreflang for each equivalent page.
- Have a fluent reader review the title, body and CTA, not only navigation labels.
Start with content and responsibilities per language
A multilingual website needs separate, useful language versions and a management agreement. Decide which services and pages are actually translated, who follows up changes and who can handle requests in that language. A translated menu alone is not a complete language version.
- Translate main content, title, description, buttons, form labels and errors together.
- Check relevant terms and privacy information for every published language.
- Send a language choice to the equivalent page when it actually exists.
Use stable URLs and real language alternatives
A language path such as /nl/, /en/ or /fr/ separates versions; slugs do not have to differ in every language. Give each real language page its appropriate canonical. Use hreflang only for equivalent published pages, with absolute URLs, the page itself and return links.
Illustrative scenario: a service exists in Dutch and English but has not been translated into French. Do not link a French alternative to the homepage as if it contained the same service. An optional x-default points to a deliberately chosen default destination.
Laravel 13: routes are not translations
The route fragment assumes use Illuminate\Support\Facades\Route in routes/web.php and an existing pages.home view. The prefix and route name organise URLs. The project must also set the locale and load genuinely translated content; the fragment does not do this automatically.
foreach (['nl', 'en', 'fr'] as $locale) {
Route::prefix($locale)
->name("localized.{$locale}.")
->group(function () use ($locale): void {
Route::view('/', 'pages.home')->name('home');
});
}Language links in a Blade template
The Blade fragment expects validated absolute URLs in $alternates, including the current page. $defaultUrl is the chosen x-default. Do not include unpublished translations, and check the same set on every equivalent language page.
@foreach ($alternates as $locale => $url)
<link rel="alternate" hreflang="{{ $locale }}" href="{{ $url }}">
@endforeach
<link rel="alternate" hreflang="x-default" href="{{ $defaultUrl }}">Maintain changes together
- Record which language versions need each content change.
- Test navigation, request context, form errors and thank-you information per language.
- Check long translated buttons and accessible language selection on mobile.
- Check canonicals, language links, sitemap and internal links after publication.
An additional language does not guarantee traffic or requests. Prioritise languages using the real audience and the content and follow-up you can provide.
Last updated:


