Back to Course |
Multi-Language Laravel 11: All You Need to Know

mcamara/laravel-localization

We've covered the core string Localization, but there are more aspects that we can translate. For example, routes:

Take a look at the URL bar

In the images, you should see that the routes are translated as well. This is done by the mcamara/laravel-localization package.

This package helps you manage your routes in multiple languages. It also provides a great set of middlewares and helpers to help you with translations - such as detecting the user's language and redirecting them to the correct route, translating routes, etc.


Installation

To install the package, there are quite a few steps. First, we need to install the package:

composer require mcamara/laravel-localization

Then, we need to publish the config file:

php artisan vendor:publish --provider="Mcamara\LaravelLocalization\LaravelLocalizationServiceProvider"

And finally register the middleware in the app/Http/Kernel.php file:

app/Http/Kernel.php

protected $routeMiddleware = [
// ...
'localize' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class,
'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class,
'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class,
'localeCookieRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleCookieRedirect::class,
'localeViewPath' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class
];

This way, we have everything we need to start translating!


Setting Up the Routes

To set our routes, we need to modify how they are defined a little bit by adding a parent group:

routes/web.php

Route::group([
'prefix' => LaravelLocalization::setLocale(),
'middleware' => ['localeSessionRedirect', 'localizationRedirect']
], function () {
Route::get('/', function () {
return view('welcome');
});
 
// ...
 
require __DIR__ . '/auth.php';
});

This code will achieve the following:

  • Prefix the routes with a locale (e.g. /en/ or /es/)
  • Redirect the user to the correct locale if they are not using it

Combined with default configuration values found in config/laravellocalization.php - it will also attempt to guess the user's locale based on the browser's settings.


Enabling Different Languages

To enable different languages, we need to modify the config/laravellocalization.php file:

config/laravellocalization.php

// ...
'supportedLocales' => [
'en' => ['name' => 'English', 'script' => 'Latn', 'native' => 'English', 'regional' => 'en_GB'],
//'en-AU' => ['name' => 'Australian English', 'script' => 'Latn', 'native' => 'Australian English', 'regional' => 'en_AU'],
//'en-GB' => ['name' => 'British English', 'script' => 'Latn', 'native' => 'British English', 'regional' => 'en_GB'],
//'en-CA' => ['name' => 'Canadian English', 'script' => 'Latn', 'native' => 'Canadian English', 'regional' => 'en_CA'],
//'en-US' => ['name' => 'U.S. English', 'script' => 'Latn', 'native' => 'U.S. English', 'regional' => 'en_US'],
'es' => ['name' => 'Spanish', 'script' => 'Latn', 'native' => 'español', 'regional' => 'es_ES'],
],
// ...

Adding the Language Switcher

Lastly, we need to add a language switcher to our application. We can do this by adding a simple blade template:

resources/views/layouts/navigation.blade.php

{{-- ... --}}
@foreach(LaravelLocalization::getSupportedLocales() as $localeCode => $properties)
<x-nav-link rel="alternate" hreflang="{{ $localeCode }}"
:active="$localeCode === app()->getLocale()"
href="{{ LaravelLocalization::getLocalizedURL($localeCode, null, [], true) }}">
{{ ucfirst($properties['native']) }}
</x-nav-link>
@endforeach
<x-dropdown align="right" width="48">
{{-- ... --}}

This will add a language switcher to the top of the page:


Fixing Route Caching

By default, the Mcmara package will not work with route caching. To fix this, we need to add a few lines to the RouteServiceProvider.php file:

app/Providers/RouteServiceProvider.php

// ...
 
class RouteServiceProvider extends ServiceProvider
{
use \Mcamara\LaravelLocalization\Traits\LoadsTranslatedCachedRoutes;
 
// ...

And change the artisan command we use. Instead of php artisan route:cache we should use php artisan route:trans:cache.

Clearing route cache works with php artisan route:clear but it will leave some mess in the bootstrap/cache folder. To avoid it - we should also use the php artisan route:trans:clear command.

Displaying All Routes

Another command that differs while using this package is php artisan route:list. While it still works, it will only give you a base overview:

But if we use php artisan route:trans:list {locale} we will get a more detailed overview:


Extended Package Functionality

While we've covered the base package functionality to get your routes going - there are a few more things that you can do with the package.

  • Show or hide the default locale in the URL
  • Ignore specific routes
  • Translating the routes

All of these require a bit more work, so let's get started!

Showing or Hiding the Default Locale in URL

By default, the Mcmara package will show the default locale in the URL:

/en/dashboard /es/dashboard

This is not always desirable, so we can change this by modifying the config/laravellocalization.php file:

config/laravellocalization.php

// ...
'hideDefaultLocaleInURL' => true,
// ...

After this change you'll have the following URLs:

/dashboard /es/dashboard

Ignoring Specific Routes

There are cases where it doesn't matter if the route is localized or not. For example, a route that checks for messages from a queue.

routes/web.php

 
Route::group([
'prefix' => LaravelLocalization::setLocale(),
'middleware' => ['localeSessionRedirect', 'localizationRedirect']
], function () {
// ...
 
Route::get('/queue-check', QueueCheckController)->name('queue.check');
 
// ...
});

Trying to load this page (or make a JSON request to it) will result in a URL change to:

/en/queue-check

Which might not be what we want. Even if we defined the route in a prefixed group - we can ignore the route by adding it to the config/laravellocalization.php file:

config/laravellocalization.php

// ...
'urlsIgnored' => [
'/queue-check',
],
// ...

And now it will not contain any locale prefix:

/queue-check

Translating the Routes

Another great extension to the package is the ability to translate the routes. This is especially useful if you want to have a different URL for the same page in different languages. For example, if you want to have a different URL for the dashboard page in Spanish:

/en/dashboard /es/panel

To achieve this, we need to modify the routes/web.php file and add a middleware:

routes/web.php

Route::group([
'prefix' => LaravelLocalization::setLocale(),
'middleware' => ['localeSessionRedirect', 'localizationRedirect', 'localize'] // <- Add `localize` middleware
], function () {
// ...
});

This way, we told the system that we expect the routes to be translated. Now we need to add the translations to the resources/lang/{locale}/routes.php file:

resources/lang/en/routes.php

return [
'dashboard' => 'dashboard',
];

And the translation for Spanish:

resources/lang/es/routes.php

return [
'dashboard' => 'panel',
];

The last step before seeing it in action is to add the translated routes to the routes/web.php file by adding LaravelLocalization::transRoute('routes.dashboard') instead of the route path:

routes/web.php

Route::get(LaravelLocalization::transRoute('routes.dashboard'), [DashboardController::class, 'index'])->middleware(['auth', 'verified'])->name('dashboard');

Once this is done, switching languages will switch the URL as well:

/en/dashboard /es/panel

Translated Routes Issues

While this is a great feature, there are a few issues with it. One of those is described in the package documentation - the POST method is not working with translated routes.

To fix this, you have to use the LaravelLocalization::localizeUrl($route) facade instead of the route() helper. So it might be best to translate only the GET routes.


Conclusion

This package is really versatile in terms of route localization control. Combining this with previously covered static text translation - you'll definitely have a great time with your multilingual application.


Repository: https://github.com/LaravelDaily/laravel11-localization-course/tree/lesson/packages/mcamara-laravel-localization