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

boby's avatar
Level 2

Localisation from controller

Hi, I am trying to create multi language app for multi users (so that language is applied per user). I have translation in place already, and when I change locale in config it works as expected.

When user is logged in, in his/her settings he/she can set the language (en or de) and that is stored in database with that user id. After save I do:

        $lang = Auth::user()->user_settings->language;
        App::setLocale($lang);

and locale is set (checked in session), but only for current route, so language is not applied on whole app.

I tried to find online but without much success, how to set now the language for that user on the app level? That has to be done somehow on routes level, or? Also, it would be great, that next time user is on login page that the page is also in his/her language, but without logged in user, I assume I need to set it in the cookie, and get it from there?

So my problem is that this translation is not applied even if it is set in session.

0 likes
30 replies
boby's avatar
Level 2

So I found out that I can put above code on every blade file, and it works that way, but that is obviously wrong way to do it. :(

boby's avatar
Level 2

So after searching online for solution, I found something that partially solves my problem. I used this how to: https://dev.to/fadilxcoder/adding-multi-language-functionality-in-a-website-developed-in-laravel-4ech

It works ok, but when I logout/login language is back to default. I need to go every time to settings and set language manually as in my controller this is executed after save button:

$lang = Auth::user()->user_settings->language;
return redirect (url('locale/' . $lang))->with('success','Settings saved successfully.');

After that everything is translated but when I login next time, language is not set, which is correct as I set it only here in settings.

How can I set it after login?

MichalOravec's avatar

I think in your LoginController you can add this:

/**
 * The user has been authenticated.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  mixed  $user
 * @return mixed
 */
protected function authenticated(Request $request, $user)
{
    $lang = $user_settings->language;

    App::setLocale($lang);
}

or inside authenticated method you can also add redirect.

johncarmackfan95's avatar

Would middleware solve your issue?

<?php

namespace App\Http\Middleware;

use Closure;

class SetLocale
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
	$locale = \Auth::check() 
		? auth()->user()->user_settings->language
		: config('app.locale');
			
	app()->setLocale($locale);
		
        return $next($request);
    }
}

Add it to the web middleware group.

boby's avatar
Level 2

After login it complains:

TypeError Argument 1 passed to App\Http\Controllers\Auth\LoginController::authenticated() must be an instance of App\Http\Controllers\Auth\Request, instance of Illuminate\Http\Request given, called in /home/vagrant/code/value2.test/vendor/laravel/ui/auth-backend/AuthenticatesUsers.php on line 110

MichalOravec's avatar

Import Request class in top of your LoginController:

use Illuminate\Http\Request;
boby's avatar
Level 2

@johncarmackfan95

Your solution worked, but I don't know why the one from the page I sent, didn't.

I had handle function like this:

    public function handle($request, Closure $next)
    {
        if(Session::has('locale')) {
            App::setlocale(Session::get('locale'));
        }
        return $next($request);
    }

Thx!

boby's avatar
Level 2

So to summarize, the solution that @johncarmackfan95 wrote, is working, even if I already had "middleware solution" from the page above.

To repeat, I set the language per user like this:

$lang = Auth::user()->user_settings->language;
return redirect (url('locale/' . $lang))->with('success','Settings saved successfully.');

Here the only problem is that this part with the message is not working. Message is not shown. Anyone have idea why?

MichalOravec's avatar

Do you have something in view where you show that message?

Like:

@if (Session::has('success'))
    <div class="alert alert-success">
        <ul>
            <li>{{ Session::get('success') }}</li>
        </ul>
    </div>
@endif
boby's avatar
Level 2

@michaloravec

No I don't have anything like that, but this is standard way, that I use and it is working everywhere else.

If I put:

return redirect ('/user-settings')->with('success','Settings saved successfully.');

that works. But this not:

return redirect (url('locale/' . $lang))->with('success','Settings saved successfully.');

and yes, the idea is to stay on settings page after saving changes.

MichalOravec's avatar

On url for example locale/en you redirect again right?

There you need propably reflash it again, there is documentation for it.

$request->session()->keep('success');
boby's avatar
Level 2

Sry my bad. I do have in in app.blade file:

@if ($message = Session::get('success'))
<div class="alert alert-success alert-block">
	<button type="button" class="close" data-dismiss="alert">×</button>	
        <strong>{{ $message }}</strong>
</div>
@endif


@if ($message = Session::get('error'))
<div class="alert alert-danger alert-block">
	<button type="button" class="close" data-dismiss="alert">×</button>	
        <strong>{{ $message }}</strong>
</div>
@endif

and so on, for warning & info type of message

I'll try to reflash.

boby's avatar
Level 2

@michaloravec

It is a function to update user settings:

    public function update(Request $request, UserSettings $userSettings)
    {
        $attributes['user_id'] = Auth::user()->id;
        $attributes = $this->validateGeneralSettings();    

        UserSettings::where('user_id', Auth::user()->id)->update($attributes);

        $lang = Auth::user()->user_settings->language;
        return redirect (url('locale/' . $lang))->with('success','Settings saved successfully.');

        //return redirect ('/user-settings')->with('success','Settings saved successfully.');
    }

other then this there is a validation function and index, which shows existing data in settings. Nothing else.

boby's avatar
Level 2

In web.php:

Route::get('locale/{locale}', function ($locale){
    Session::put('locale', $locale);
    return redirect()->back();
});
MichalOravec's avatar

@boby

Ok try it to change to this:

Route::get('locale/{locale}', function ($locale){
    session(['locale' =>  $locale]);

    session()->keep('success');

    return redirect()->back();
});
boby's avatar
Level 2

@michaloravec

Works that way and I see that the difference is the line:

  session()->keep('success');

but how long this message will live? Documentation says: "If you need to keep your flash data around for several requests, you may use the reflash method, which will keep all of the flash data for an additional request."

Does this mean two? If it is longer, that can cause some other problem if that message is live long enough?

Should I "forget" the key success of maybe flush all session messages?

MichalOravec's avatar

No, you don't have to, now it is ok, because it keeps just for next redirect and you do it there. So it should be everything good now.

1 like
boby's avatar
Level 2

So final thing that is left to do is translate non-authorized pages (like login page). I was thinking to do it this way:

  • after settings are saved I check if cookie e.g. lang exists and that it has value
  • if yes do nothing,
  • if no, set it

On login page I set locale based on the cookie content.

What do you think?

Is there a way to set do this for all non-authorized pages at once? Like login, reset password, register, ... so I don't do it on one by one.

boby's avatar
Level 2

But I am not sure that I know how :(

Probably I need one more middleware like for user settings, just not get the user_settings->language, but cookie value? Am I right?

Where do I put that middleware, and how to say "this middleware is for those pages like login, register, ..."

boby's avatar
Level 2

Hi again,

@michaloravec

this solution with keeping session for one more request now created a new problem. I have added cookie creation after settings are saved like this:

return redirect (url('locale/' . $lang))->with('success', __('user_settings.settings_saved'))->cookie('language', $lang, 1440);

so I simply added only

->cookie('language', $lang, 1440)

and the cookie is saved.

Problem is, in order to have a new value (language), I need to press save on settings twice, otherwise I have old value in cookie.

Or I am having something else wrong here, not related to keeping request?

MichalOravec's avatar

I don't think that problem is related to keeping session.

boby's avatar
Level 2

My problem is not the session :( somehow getting language from database is wrong:

$lang = Auth::user()->user_settings->language;

this is not updated if I don't press save twice. Have no idea why.

DB record is ok, I checked.

I can use request to get correct language, but I don't get it why above way is working from 2nd save and not from the 1st one. So strange...

boby's avatar
Level 2

So, to conclude, how I solved translation, in case someone finds it useful.

First, ofc, I have translation in place in 'lang' folder, so I will skip that part.

Then as @johncarmackfan95 suggested I created middleware, with little modification:

    public function handle($request, Closure $next)
    {
        if(! Auth::check() && (Cookie::get('lang') !== null)) {
            app()->setLocale(Cookie::get('lang'));
        }
        
        $locale = Auth::check() 
            ? auth()->user()->user_settings->language
            : config('app.locale');          
        app()->setLocale($locale);
        
        return $next($request);
    }

so I covered case when user is not logged in with the cookie, which is created in user settings page after clicking button Update:

    public function update(Request $request, UserSettings $userSettings)
    {
        $attributes['user_id'] = Auth::user()->id;
        $attributes = $this->validateGeneralSettings();    

        UserSettings::where('user_id', Auth::user()->id)->update($attributes);

        $new_language = $attributes['language'];

        return redirect (url('locale/' . $new_language))->with('success', __('user_settings.settings_saved'))->cookie('lang', $new_language, 525600);
    }

in my routes I added:

Route::get('locale/{locale}', function ($locale) {
    session(['locale' =>  $locale]);
    session()->keep('success');   
    return redirect()->back();
});

and that is it!

Big thanks to everyone on this thread!

MichalOravec's avatar

@boby You mentioned the middleware in your third post, that you used from that article.

boby's avatar
Level 2

That solution was different, and it didn't work until I change it to what @johncarmackfan95 suggested, and yesterday I "expanded" it to include non auth pages as well.

Anyhow I just wanted to summarize all in one message in case someone need it.

Thank you.

Please or to participate in this conversation.