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

OnyxException's avatar

Laravel SetLocale Middleware does not work

Hello everyone,

I am writing because I currently have a bug, namely when the language is changed, the 'de' language is taken no matter what was set. I even know the reason, because my URL /about/team looks like this. The language is always forcibly set as 1. so /en/about/team. And that's fine.

Now the problem is that even if I save the locale in the app() or session(), it should try to access it, it does not work.

I know the code below is messy, it's just because every route of mine uses {locale?} except for a few and POST requests.

SetLocale Middleware

public function handle(Request $request, Closure $next): Response
    {
        if ($request->is('sanctum/csrf-cookie')) {
            return $next($request);
        }

        if ($request->segment(1) === 'auth') {
            if ($request->segment(2) === 'redirect') {
                return $next($request);
            } else if ($request->segment(2) === 'callback') {
                return $next($request);
            };
        }

        if ($request->segment(1) === 'process') {
            return $next($request);
        }

        if ($request->segment(1) === 'assets') {
            return $next($request);
        }

        if ($request->segment(1) === 'api') {
            return $next($request);
        }

        if ($request->isMethod('post')) {
            return $next($request);
        }

        $locale = $request->segment(1);

        if (in_array($locale, ['de', 'en'])) {
            app()->setLocale($locale);
            session()->put('locale', $locale);
        } else {
            if (session()->has('locale')) {
                return redirect(session('locale') . $request->getPathInfo());
            }
            return redirect('de' . $request->getPathInfo());
        }

        return $next($request);
    }

LanguageChanger:

public function setLocale($locale)
    {
        $previousUrl = url()->previous();
        preg_match('/\/(de|en)(\/|$)/', $previousUrl, $matches);
        $currentLocale = $matches[1] ?? config('app.locale');
        $newPreviousUrl = preg_replace("/\/$currentLocale(\/|$)/", "/$locale", $previousUrl, 1);

        session()->put('previous_url', $newPreviousUrl);
        session()->put('locale', $locale);
        app()->setLocale($locale);

        return redirect()->to(session('previous_url'));
    }```
0 likes
4 replies
JussiMannisto's avatar

I know the code below is messy, it's just because every route of mine uses {locale?} except for a few and POST requests.

You could add a withoutMiddleware call to the routes that don't use this middleware. That way you could clean it up a bit and make it independent of URLs (except the locale segment).

How is the LanguageChanger::setLocale method called; where does the $locale parameter come from?

OnyxException's avatar

Hey,

I've been playing around a bit, but it's just not working. Can you maybe write me a code for the SetLocale middleware?

My goal is that if there is no value in the session and in the URL, the language that is in the config is taken, if one of the two is present, the app language is set to this. Basically, the language should always be present in the URL.

However, my links should only work with www.example.com/about/, but then the language is automatically added, i.e. www.example.com/de/about.

But then not always de but only if the above conditions are not met.

amitsolanki24_'s avatar

Try to dd that you session has value or not dd(session()->get('locale'));

And run pho artisan config:clear command sometimes it's not working because of cache issue

OnyxException's avatar

Dont work.

Middleware

public function handle(Request $request, Closure $next): Response
    {
        $langParameter = $request->segment(1);
        $fallbackLanguage = 'de';

        if ($langParameter == null) {
            $sessionLanguage = Session::get('locale');
            if ($sessionLanguage == null || !in_array($sessionLanguage, ['de', 'en'])) {
                $language = $fallbackLanguage;
            } else {
                $language = $sessionLanguage;
            }
        } else {
            $language = in_array($langParameter, ['de', 'en']) ? $langParameter : $fallbackLanguage;
        }

        app()->setLocale($language);
        session()->put('locale', $language);
        URL::defaults(['locale' => $language]);

        echo 'Language: ' . $language;
        echo 'Current Language: ' . \app()->currentLocale();

        return $next($request);
    }

Change Language:

public function setLocale($locale)
    {
        $previousUrl = url()->previous();
        preg_match('/\/(de|en)(\/|$)/', $previousUrl, $matches);
        $currentLocale = $matches[1] ?? config('app.locale');
        $newPreviousUrl = preg_replace("/\/$currentLocale(\/|$)/", "/$locale", $previousUrl, 1);

        session()->put('previous_url', $newPreviousUrl);
        session()->put('locale', $locale);
        app()->setLocale($locale);

        return redirect()->to(session('previous_url'));
    }

Please or to participate in this conversation.