- Automatically register a route for each locale you wish to support.
- Generate localized route URL's in the simplest way using the
route()
helper. - Redirect to localized routes using the
redirect()->route()
helper. - Allow routes to be cached.
- Let you work with routes without thinking too much about locales.
- Optionally translate each segment in your URI's.
- PHP >= 7.1
- Laravel >= 5.6
composer require codezero/laravel-localized-routes
Laravel will automatically register the ServiceProvider.
php artisan vendor:publish --provider="CodeZero\LocalizedRoutes\LocalizedRoutesServiceProvider" --tag="config"
You will now find a localized-routes.php
file in the config
folder.
Add any locales you wish to support to your published config/localized-routes.php
file:
'supported-locales' => ['en', 'nl', 'fr'],
Example:
// Not localized
Route::get('home', HomeController::class.'@index')
->name('home');
// Localized
Route::localized(function () {
Route::get('about', AboutController::class.'@index')
->name('about');
Route::name('admin.')->group(function () {
Route::get('admin/reports', ReportsController::class.'@index')
->name('reports.index');
});
});
In the above example there are 5 routes being registered. The routes defined in the Route::localized
closure are automatically registered for each configured locale. This will prepend the locale to the route's URI and name.
URI | Name |
---|---|
/home | home |
/en/about | en.about |
/nl/about | nl.about |
/en/admin/reports | en.admin.reports.index |
/nl/admin/reports | nl.admin.reports.index |
You can get the URL of your named routes as usual, using the route()
helper.
Normally you would have to include the locale whenever you want to generate a URL:
$url = route(app()->getLocale().'.admin.reports.index');
Because that's rather ugly, this package overwrites the route()
function and the underlying UrlGenerator
class with an additional, optional $locale
argument and takes care of the locale prefix for you. If you don't specify a locale, either a normal, non-localized route or a route in the current locale is returned.
route($name, $parameters = [], $absolute = true, $locale = null)
A few examples:
app()->setLocale('en');
app()->getLocale(); // 'en'
$url = route('home'); // /home (normal routes have priority)
$url = route('about'); // /en/about (current locale)
// Get specific locales...
// This is most useful if you want to generate a URL to switch language.
$url = route('about', [], true, 'en'); // /en/about
$url = route('about', [], true, 'nl'); // /nl/about
// You could also do this, but it kinda defeats the purpose...
$url = route('en.about'); // /en/about
$url = route('en.about', [], true, 'nl'); // /nl/about
Note: in a most practical scenario you would register a route either localized or non-localized, but not both. If you do, you will always need to specify a locale to get the URL, because non-localized routes always have priority when using the
route()
function.
Laravel's Redirector
uses the same UrlGenerator
as the route()
function behind the scenes. Because we are overriding this class, you can easily redirect to your routes.
return redirect()->route('home'); // redirects to /home
return redirect()->route('about'); // redirects to /en/about (current locale)
You can't redirect to URL's in a specific locale this way, but if you need to, you can of course just use the route()
function.
return redirect(route('about', [], true, 'nl')); // redirects to /nl/about
If you want to translate the segments of your URI's, create a routes.php
language file for each locale you configured:
resources
└── lang
├── en
│ └── routes.php
└── nl
└── routes.php
In these files, add a translation for each segment.
// lang/nl/routes.php
return [
'about' => 'over',
'us' => 'ons',
];
Now you can use our Lang::uri()
macro during route registration:
Route::localized(function () {
Route::get(Lang::uri('about/us'), AboutController::class.'@index')
->name('about.us');
});
The above will generate:
- /en/about/us
- /nl/over/ons
If a translation is not found, the original segment is used.
Placeholders are not translated via language files. These are values you would provide via the route()
function. The Lang::uri()
macro will skip any placeholder segment.
If you have a model that uses a route key that is translated in the current locale, then you can still simply pass the model to the route()
function to get translated URL's.
An example...
class Post extends \Illuminate\Database\Eloquent\Model
{
public function getRouteKey()
{
$slugs = [
'en' => 'en-slug',
'nl' => 'nl-slug',
];
return $slugs[app()->getLocale()];
}
}
TIP: checkout spatie/laravel-translatable for translatable models.
Route::localized(function () {
Route::get('posts/{post}', PostsController::class.'@show')
->name('posts.show');
});
app()->setLocale('en');
app()->getLocale(); // 'en'
$post = new Post;
$url = route('posts.show', $post); // /en/posts/en-slug
$url = route('posts.show', $post, true, 'nl'); // /nl/posts/nl-slug
In production you can safely cache your routes per usual.
php artisan route:cache
composer test
If you discover any security related issues, please e-mail me instead of using the issue tracker.
See a list of important changes in the changelog.
The MIT License (MIT). Please see License File for more information.