How to create localizable (i18n) routes in Laravel

Updated: January 15, 2024 By: Guest Contributor Post a comment

Introduction

In a multilingual web application, having URLs that reflect the chosen language can enhance the user experience and potentially improve SEO. Laravel, a popular PHP web application framework, offers a comprehensive set of localization tools. In this tutorial, you’ll learn how to create localizable Internationalization (i18n) routes with Laravel.

Understanding Localization in Laravel

Laravel’s localization features allow you to create multilingual websites by offering an easy way to retrieve strings in various languages. To manage language selection across routes, you also need to adapt your routing design. This allows users to switch between languages while staying on the same page.

Setting Up the Environment

Before creating localizable routes, make sure you’re running the latest version of Laravel and have created a new project or are working on an existing one. Follow the Laravel installation documentation if you haven’t already set up your environment.

composer create-project laravel/laravel your_project_name

Basic Localized Routing

To start with, internally define a set of supported locales in a configuration file or environment variable. For the purpose of this tutorial, let’s assume English (en) and Spanish (es) as our supported languages. Open up ‘config/app.php’ and add the following:

'supported_locales' => ['en', 'es'],

In your ‘routes/web.php’, set up a route group with a prefix for the locale:

Route::group(['prefix' => '{locale}'], function () {
    Route::get('/', function () {
        return view('welcome');
    });
});

Now the route to your welcome page can be accessed via ‘/en’ and ‘/es’ with respective language contents. Make sure your application can detect and apply the correct language.

Middlewares for Locale Detection

To handle locale detection and application, you can create middleware in Laravel. Use the Artisan CLI:

php artisan make:middleware LocaleMiddleware

Add the locale detection logic into the ‘handle’ method:

public function handle($request, Closure $next)
{
    $locale = $request->route('locale');
    if (in_array($locale, config('app.supported_locales'))) {
        app()->setLocale($locale);
    }
    return $next($request);
}

And register the middleware in the ‘app/Http/Kernel.php’ file under the ‘$routeMiddleware’ array:

'setlocale' => \App\Http\Middleware\LocaleMiddleware::class,

Apply our new ‘setlocale’ middleware to the localized route group:

Route::group(['prefix' => '{locale}', 'middleware' => 'setlocale'], function() {
    // Your localized routes go here
});

Generating Localized URLs

With route localization, you’ll often need to generate URLs that are properly localized. Laravel allows you to generate URLs using the ‘route’ function:

$localizedUrl = route('your_route_name', ['locale' => app()->getLocale()]);

To keep templates clean, consider creating a helper function to handle this functionality.

Advanced Route Localization

For a more granular control, consider localizing individual route names and ensuring that reversing to a named route respects the chosen locale.

You can define named routes as follows:

Route::group(['prefix' => '{locale}', 'as' => '{locale}.'], function() {
    Route::get('/contact', function () {
        // Contact page logic
    })->name('contact');

    // More localized routes
});

This way, you can reference routes with their locale prefix, like so:

$localizedContactUrl = route(app()->getLocale().'.contact');

Locale Switcher

To assist users in switching languages, you can create a locale switcher on your application’s layout. Loop through supported locales and generate switch links:

<nav>
@foreach(config('app.supported_locales') as $locale)
    <a href="{{ route(Route::currentRouteName(), $locale) }}">{{ strtoupper($locale) }}</a>
@endforeach
</nav>

Ensure you include logic to handle the case where the current route is not named or when locale parameters are not required.

Database Driven Route Translation

If your application requires dynamic route translation based on stored content, consider integrating a package or implementing a controller that can resolve localized slugs to model instances. For example:

Route::get('{locale}/{slug}', 'ContentController@show');

The ‘ContentController@show’ method would then look up the slug considering the locale and return the appropriate view with the content.

Conclusion

Localizing routes in a Laravel application is not only beneficial for user experience but also complements the powerful localization features offered by the framework. As we’ve seen, with a few middleware and careful routing conventions, Laravel allows for the seamless integration of internationalized routes into your applications.