Great question! Translating multilingual URLs in Laravel is a common challenge and the approach can depend on your site's needs, SEO strategy, and maintainability considerations.
1. URL Structures: Localized Only Locale vs. Full URL Translation
-
Locale Only (e.g. /en/about, /fr/about):
This is easier to maintain, as you use a "slug" once and just prepend the locale. It's the standard LaravelRoute::group(['prefix' => '{locale}'], ...)approach. -
Full URL Translation (e.g. /en/about, /fr/a-propos):
This is more "user friendly" and SEO-optimized for each language, but is also significantly more complex to implement and maintain.
2. Translate ALL URLs?
If your target is better user experience and SEO in each language, translating URLs is recommended. European users in particular expect to see their language in the entire URL, not just the content.
3. Translation Management: Static Files vs. Database
- For a limited set of routes/pages, keeping translated slugs in
langfiles (e.g.lang/en/routes.phpandlang/fr/routes.php) is manageable. - For lots of dynamic content (e.g. blog posts), storing slugs in the database per language is best.
Recommended Approach
For mostly static routes, keep translations in lang files. For dynamic content, store slugs in the database.
Redesigning your Laravel routes for localization is necessary if you want truly translated URLs.
Here's how you can handle static translated URLs in Laravel:
1. In your lang files:
resources/lang/en/routes.php
return [
'about' => 'about',
'contact' => 'contact',
];
resources/lang/fr/routes.php
return [
'about' => 'a-propos',
'contact' => 'contact',
];
2. Generating routes in web.php:
foreach (['en', 'fr'] as $locale) {
App::setLocale($locale);
$aboutSlug = trans('routes.about');
Route::get("$locale/$aboutSlug", function () use ($locale) {
App::setLocale($locale);
return view('about');
})->name("$locale.about");
}
3. Generating URLs in Blade:
<a href="{{ route(app()->getLocale().'.about') }}">
{{ __('About Us') }}
</a>
For dynamic slugs (e.g., blog posts):
- Store a
slugfor each language in thepoststable. - Fetch and use the appropriate slug per locale in route models and URL generations.
Resources
- Laravel: Localized Routes
- Spatie Laravel Translatable
- Laravel docs: Localization
- Symfony Routing and i18n (conceptually similar)
Conclusion
- Translating all URLs (not just content) is best for international audiences and SEO.
- For static routes, translation via
langfiles works well. - For dynamic content, use database translations.
- For easier implementation, check out mcamara/laravel-localization, which handles much of this for you.
Let me know if you want to see a full code example for dynamic routes or any specific implementation details!