Laravel multilingual application

When working with multilingual applications, I like to have clear URls without the language displayed. Therefore I use session to manage my localization. I have the following setup:

/app/Http/Middleware/TranslateMiddleware


public function handle($request, Closure $next)
{
    if( !Session::has('locale' )){
        $browserLanguage = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); //read browser language

        if ( array_key_exists($browserLanguage, Config::get('languages')) ) {
            Session::set('locale', $browserLanguage);
        } else {
            Session::set('locale', 'en');
        }
    }

    //Simply set language from session 
    App::setlocale(Session::get('locale'));

    return $next($request);
}

What happens is, first I check if there is already a locale saved in the session. If not, I get the browser language, and check if that language in my languages array from ‘/config/language.php’, which simply returns an array of languages. If the browser language is not in my languages array, I default back to English. Now that the language is set in the session, we need to set it to the app as well `App::setlocale()`.

Next, add your middleware to the Kernel, then wrap all your routes that need localization in a group and pass this middleware to the group


// app/Http/Kernel.php
...
protected $routeMiddleware = [
    ...
    'translate' => \App\Http\Middleware\TranslateMiddleware::class
];



// routes/web.php 
...
Route::group(['middleware' => 'translate'], function() {
    Route::get('home', 'HomeController@index');
});

Note: Don’t forget ‘use App;’, ‘use Config;’ and ‘use Session;’ on top of your middleware

What if the user decides to manually change the language?

Simple. Define a get route that takes one parameter. That parameter is going to be the language (2 letters). Then define a function in a controller, and call App::setlocale() again, passing it the URL parameter. But first, check if the language in parameter is in the languages array.


// route/web.php
...
Route::get('language/{language}', 'HomeController@setLanguage');


// HomeController
public function setLanguage($language)
{
    if ( array_key_exists($language, Config::get('languages')) ) {
        Session::set('locale', $language);
        App::setlocale($language);
    }

    return redirect()->back();
}

And voila!

At least Man U won and is getting closer to 4th position. If we defeat City this week, I think that would almost guarantee a 4th place.