How to use multiple languages in your Laravel 5 website

...

The following will make domain.com/{locale} available to your website.

What you need to use multiple locales is three things.

Add list of available locales to an array.

Prefix all your routes with current locale.

A language middleware that checks if user is using a valid locale.

Step 1: Add your locales

Open up config/app.php and add the following below 'locale' => 'xx'.

'locales' => ['en' => 'English', 'sv' => 'Swedish'],

Modify this array with your desired locales.

Step 2: Prefix your routes

To prefix our routes, we change the map method in app/Providers/RouteServiceProvider.php. Change the map method to the following:

public function map(Router $router, Request $request)
{
    $locale = $request->segment(1);
    $this->app->setLocale($locale);

    $router->group(['namespace' => $this->namespace, 'prefix' => $locale], function($router) {
        require app_path('Http/routes.php');
    });
}

Then add this to the top of the file:

use Illuminate\Routing\Router;
use Illuminate\Http\Request;
Example at Github

Step 3: Create a language middleware

Now create a file named Language.php in app/Http/Middleware with this content:

<?php namespace App\Http\Middleware;

use Closure;
use Illuminate\Routing\Redirector;
use Illuminate\Http\Request;
use Illuminate\Foundation\Application;
use Illuminate\Contracts\Routing\Middleware;

class Language implements Middleware {

    public function __construct(Application $app, Redirector $redirector, Request $request) {
        $this->app = $app;
        $this->redirector = $redirector;
        $this->request = $request;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // Make sure current locale exists.
        $locale = $request->segment(1);

        if ( ! array_key_exists($locale, $this->app->config->get('app.locales'))) {
            $segments = $request->segments();
            $segments[0] = $this->app->config->get('app.fallback_locale');

            return $this->redirector->to(implode('/', $segments));
        }

        $this->app->setLocale($locale);

        return $next($request);
    }

}

Now make that middleware run on all requests by adding it to the $middleware property in app/Http/Kernel.php. It is recommended to add it to the top of the array.

protected $middleware = [
    'App\Http\Middleware\Language',
    'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
    'Illuminate\Cookie\Middleware\EncryptCookies',
    'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
    'Illuminate\Session\Middleware\StartSession',
    'Illuminate\View\Middleware\ShareErrorsFromSession',
    'Illuminate\Foundation\Http\Middleware\VerifyCsrfToken',
];

You are now set to go.

Example repo

I have an example repository available at

https://github.com/Marwelln/laravel-multiple-locales

– clone it to test it out or if you are unsure how it works.

Written by: Marwelln


 
Circle Image
 
 
Arnau
Posts:  1
Points:  1
 
 
 
1 year ago
 

Hello,

i've been trying to implement this, but i seem to get a loop error : ERR_TOO_MANY_REDIRECTS.

The main reason (i guess) it's because i have an admin zone controled by an admin middleware.

All admin resources are inside 'admin' middleware group except /admin/login (post & get) that are inside your language middleware (which uses laravel 'web' middleware).

Here's my routes example :

Route::group([ 'middleware' => 'lang'], function () { Route::get('/',
function () {
return view('welcome'); }); Route::get('/{lang}/{url?}/{subUrl?}', '[email protected]');

Route::get('/admin/login',[ 'as' => 'adminLoginForm', 'middleware' => 'admin', 'uses' => '[email protected]', ]); //el metode login no esta definit al controlador, es per herencia Route::post('/admin/login',[ 'middleware' => 'admin', 'as' => 'adminLogin', 'uses' => 'Auth\[email protected]', ]); });

Route::group([ 'middleware' => 'admin' ], function () { //admin stuff });

After implementing your solution, all i get is redirect loop error, doesn't matter if its /admin or /whatever.

What I'm trying to do is get my app to prefix with the locale on every request except when it's admin (and some others to render image, etc).

Am I doing something terribly wrong?

In a short future, i'm gonna have a route in the likes of /{locale}/{url?}/{subUrl?} , in a 'custom cms' style. Is that gonna interfere with the language middleware?

Thanks in advance.

 
 
Circle Image
 
 
infigic
Posts:  1
Points:  1
 
 
 
3 months ago
 

Thx for the brief information

 
 
Circle Image
 
 
Sidor
Posts:  1
Points:  1
 
 
 
2 weeks ago
 

Thanks a lot, solid tutorial.


http://blendberg.com/pl/aktualnosci