Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

zoransa's avatar

Where to setLocale in laravel 5 on multilingual - multidomain app

Hey!

Lets say I have

example.com en

ezample.de de

example.co.il he

ezamplearabic.com ar

so you get idea ~15 domains and one website. There are two approaches for products they all have the same 'id' across domains so there is product and product_lang table that contains translations of language specific stuff and en_articles, de_articles, he_articles tables for Articles Eloquent model that is select based on domain we access. Just to note there is one document root for all domains and just based on domain name laravel should set locale and users cannot choose different language on the same domain they can only switch domains to switch language.

The question is where to put this localization that will boot early in app and set up everything even before midlware etc.

0 likes
15 replies
fulup's avatar

I'm also searching for the best answer for language preference. I just publish a small demo on Social Login with a language selection in the home page. Demo is visible at http://oidconnect.breizhme.net/demo/openidconnect/home

The only working model, I found it to store my user language preference in session and then retrieve it from controller constructor. I also tried to retrieve it from route.php but it looks like this file is executed before the session is in place. I then tried in access middleware. But even if in middleware I can retrieve language from user session, if I do a App::setLocale($lang) as this level it is forgotten before I reach my controller.

In ended up with following call in my controller parent class. It works, but I'm not sure that it is be the place where it should be.

    public function __construct () {
        $lang = Session::get ('locale');
        if ($lang != null) \App::setLocale($lang);
    }
2 likes
bestmomo's avatar

I made an App middleware set in global stack after Illuminate ones to manage locale and other stuff. It works fine.

2 likes
fulup's avatar

BrestMono could explain your "in global stack after Illuminate". When I try 'App::setLocale($lang);' the selection was lost before I enter my controllers.

Question: where do you declare your Middleware in order to make the called automatic for every pages and late enough for the selection to be still valid where entering Controllers methods ?

pmall's avatar

Anywhere in the protected $routeMiddleware array of the app/Http/Kernel.php file.

    /**
     * The application's route middleware.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth' => 'Asgard\Http\Middleware\Authenticate',
        'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
        'guest' => 'Asgard\Http\Middleware\RedirectIfAuthenticated',
        'locale' => 'Your\Middleware\Namespace',
    ];

Then you can localize routes :

$router->group(['middleware' => 'locale'], function($router)
{
  $router->get('a/localized/route', ...);
});
bestmomo's avatar

@fulup there :

/**
 * The application's global HTTP middleware stack.
 *
 * @var array
 */
protected $middleware = [
    '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',
    'App\Http\Middleware\App'
];
fulup's avatar

This is almost what I tried and I was loosing my language preference. Are your using \App::setLocale($lang); call or something else in your middleware ?

bestmomo's avatar
Level 52

@fulup this is my middleware :

<?php namespace App\Http\Middleware;

use Closure, Session, Auth;

class App {

    /**
     * The availables languages.
     *
     * @array $languages
     */
    protected $languages = ['en','fr'];

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if(!Session::has('locale'))
        {
            Session::put('locale', $request->getPreferredLanguage($this->languages));
        }

        app()->setLocale(Session::get('locale'));

        if(!Session::has('statut')) 
        {
            Session::put('statut', Auth::check() ?  Auth::user()->role->slug : 'visitor');
        }

        return $next($request);
    }

}

You can see it in action in my example.

7 likes
firatakandere's avatar

I created a middleware like that:

<?php namespace App\Http\Middleware;

use Closure;
use Session;
use App;
use Config;

class Locale {

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $language = Session::get('language', Config::get('app.locale'));
        App::setLocale($language);

        return $next($request);
    }

}

and added it to protected $middleware array of App/Http/Kernel.php which will make it loaded automatically.

    /**
     * The application's global HTTP middleware stack.
     *
     * @var array
     */
    protected $middleware = [
        'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
        'Illuminate\Cookie\Middleware\EncryptCookies',
        'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
        'Illuminate\Session\Middleware\StartSession',
        'Illuminate\View\Middleware\ShareErrorsFromSession',
        'App\Http\Middleware\VerifyCsrfToken',
        'App\Http\Middleware\Locale',
    ];
3 likes
fruizcasas's avatar

Hi. I have created a new LocaleController to change the locale option using cookies

<?php namespace App\Http\Controllers;

use App\Http\Requests;
use App\Http\Controllers\Controller;

use Illuminate\Http\Request;
use URL;
use Cookie;

class LocaleController extends Controller {

    public function setLocale($locale = 'en')
    {
        if (! in_array($locale,['en','es']))
        {
            $locale = 'en';
        }
        Cookie::queue('locale', $locale);
        return redirect(url(URL::previous()));
    }
}

And a route like this:

...
Route::get('locale/{locale?}',
    [
        'as' => 'locale.setlocale',
        'uses' => 'LocaleController@setLocale'
    ]);
...

So the Locale middleware needs to be modified to this

<?php namespace App\Http\Middleware;
use Carbon\Carbon;
use Closure;
use App;
use Config;

class Locale {
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $locale = $request->cookie('locale', Config::get('app.locale'));
        App::setLocale($locale);
        Carbon::setLocale($locale);

        return $next($request);
    }
}

Yours.

1 like
bhoopal's avatar

hi guys can you tell me which process to set locale is best against speed,loading time span

andy's avatar

Does this work like a language switcher with routes or just an over all site language setting?

OmarMakled's avatar

my way

app/config/app.php

'languages' =>  ['ar','en','fr']

app/Jobs/ChangeLocale.php

<?php

namespace App\Jobs;

use App\Jobs\Job;
use Illuminate\Contracts\Bus\SelfHandling;

class ChangeLocale extends Job implements SelfHandling
{
    protected $lang;

    public function __construct($lang)
    {
        $this->lang = $lang;
    }

    public function handle()
    {
        session()->put('locale',$this->lang);
    }
}

app/Jobs/SetLocale.php

<?php

namespace App\Jobs;

use App\Jobs\Job;
use Illuminate\Contracts\Bus\SelfHandling;

class setLocale extends Job implements SelfHandling
{

    protected $languages;

    public function __construct()
    {
        $this->languages = config('app.languages');
    }

    public function handle()
    {
        if(!session()->has('locale'))
        {
            session()->put('locale', \Request::getPreferredLanguage($this->languages));
        }

        app()->setLocale(session('locale'));
    }
}

app/Http/Middleware/Localization.php

<?php

namespace App\Http\Middleware;

use Closure;

use App\Jobs\SetLocale;
use Illuminate\Bus\Dispatcher as BusDispatcher;

class Localization
{

    protected $bus;

    protected $setLocale;

    public function __construct(BusDispatcher $bus,SetLocale $setLocale)
    {
        $this->bus = $bus;
        $this->setLocale = $setLocale;
    }

    public function handle($request, Closure $next)
    {
        $this->bus->dispatch($this->setLocale);
        return $next($request);
    }
}

app/Http/Kernel.php

protected $middleware = [
        \App\Http\Middleware\Localization::class,
        ...
];

app/Http/Controllers/HomeController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

use App\Jobs\ChangeLocale;

class HomeController extends Controller
{

    public function language(Request $request)
    {
        $changeLocale = new ChangeLocale($request->input('lang'));
        $this->dispatch($changeLocale);

        return redirect()->back();
    }
}

app/Http/routes.php

Route::get('language','HomeController@language');

app/resources/views/_nav.blade.php

<div class="dropdown">
      <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
        Languages
        <span class="caret"></span>
      </button>
      <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
        @foreach(config('app.languages') as $lang)
           <li class="{{ session('locale') == $lang ? 'active' : '' }}">
                <a href="/language?lang={{ $lang }}" >{{ $lang }}</a>
           </li>
        @endforeach
      </ul>
</div>
5 likes
rajcsanyiz's avatar

It is a superb implementation. I change a little logic to my fit.

My URL pattern is: /[hu/en/ge]/{pagecode} example: http://mysite.com/en/about

/resources/views/pages/index.blade.php

<body>
   {{-- multilang header--}}
    @include('layouts._nav_'.session('locale'))

    {{-- content --}}
    <main class="pt-4 content-auto-height">
        <div class="container">
            @yield('content')
        </div>
    </main>

    {{-- multilang footer --}}
    @include('layouts._footer_'.session('locale'))
</body>

/app/Http/Controllers/PageController

<?PHP
    private function index(Request $request, $lang, $page_code ) 
   {        
        $changeLocale = new ChangeLocale($lang);
        $this->dispatch($changeLocale);


app/Jobs/SetLocale.php

<?PHP
  public function handle()
    {
        app()->setLocale(session('locale', config('app.locale')));
    }
Maksanzhi's avatar

Hi omar.makled, Please can you advice? Why redirect to login page and no change language. I did everything by your instructions.

bbdangar's avatar

Didn't work for me. session('locale') is in null before middleware.

I tried this way...

created new request class LocaleRequest and inject this request in controller methods.

LocalRequest.php

`<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest; use App;

class LocaleRequest extends FormRequest { /** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { return true; }

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    App::setLocale(session('locale', 'en'));

    return [
        //
    ];
}

`

Please or to participate in this conversation.