abkrim's avatar
Level 13

How to change language in Laravel 11

I'm looking for solution for change locale in Laravel 11.

web.php

Route::get('/language/{locale}', function ($locale) {
    session()->put('locale', $locale);
    return redirect()->back();
})->name('locale');

header.blade.php

<div class="dropdown">
        <div tabindex="0" role="button" class="btn btn-ghost">
            {{ __('original.language') }}
        </div>
        <ul tabindex="0" class="menu menu-sm dropdown-content mt-3 p-2 shadow bg-base-100 rounded-box w-52">
            <li>
                <a href="/{{ route('locale', 'es') }}">
                    <div>
                        <x-flag-country-es class="w-6 h-6" />
                    </div>
                </a>
            </li>
            <li>
                <a href="/{{ route('locale', 'en') }}">
                    <div>
                        <x-flag-country-uk class="w-6 h-6" />
                    </div>
                </a>
            </li>
            <!-- Añade tantos idiomas como necesites -->
        </ul>
    </div>

But get 404 ... URL back is https://baytuka.test/https://baytuka.test/language/en

Any help ?

0 likes
5 replies
LaryAI's avatar
Level 58

It looks like the issue you're encountering with the 404 error is due to the way the URL is being generated in your Blade template. The problem is that the href attribute in your anchor tags is incorrectly appending the full route URL to the base URL, resulting in a malformed URL.

Here's how you can fix it:

  1. Correct the URL generation in the Blade template: You should use the route helper function correctly to generate the URL. Ensure that you do not prepend a slash (/) before the route function call, as route already generates a complete URL.

  2. Ensure the session locale is used: Make sure that the application is actually using the locale stored in the session. This typically involves setting the locale in a middleware.

Here's the corrected version of your Blade template and additional steps to ensure the locale changes take effect:

Updated Blade Template (header.blade.php)

<div class="dropdown">
    <div tabindex="0" role="button" class="btn btn-ghost">
        {{ __('original.language') }}
    </div>
    <ul tabindex="0" class="menu menu-sm dropdown-content mt-3 p-2 shadow bg-base-100 rounded-box w-52">
        <li>
            <a href="{{ route('locale', 'es') }}">
                <div>
                    <x-flag-country-es class="w-6 h-6" />
                </div>
            </a>
        </li>
        <li>
            <a href="{{ route('locale', 'en') }}">
                <div>
                    <x-flag-country-uk class="w-6 h-6" />
                </div>
            </a>
        </li>
        <!-- Add as many languages as you need -->
    </ul>
</div>

Middleware for Setting Locale

Create a middleware to set the application locale based on the session value.

  1. Generate Middleware:

    php artisan make:middleware LocaleMiddleware
    
  2. Implement Middleware (app/Http/Middleware/LocaleMiddleware.php):

    namespace App\Http\Middleware;
    
    use Closure;
    use Illuminate\Http\Request;
    use App;
    
    class LocaleMiddleware
    {
        public function handle(Request $request, Closure $next)
        {
            if (session()->has('locale')) {
                App::setLocale(session()->get('locale'));
            }
    
            return $next($request);
        }
    }
    
  3. Register Middleware: Add the middleware to the web middleware group in app/Http/Kernel.php:

    protected $middlewareGroups = [
        'web' => [
            // other middleware
            \App\Http\Middleware\LocaleMiddleware::class,
        ],
    ];
    

With these changes, your application should correctly change the locale based on the user's selection and redirect back without generating malformed URLs.

abkrim's avatar
Level 13

@LaryAI app/Http/Kernel.php is not valid for Laravel 11?

Correct in Laravel 11

->withMiddleware(function (App\Http\Middleware\LocaleMiddleware $middleware) {
        $midleware->append(LocaleMiddleware::class);
};

Thanks.

1 like
pmeneses97's avatar

@abkrim If someone still has issues with changing locale,

1. Clear all caches

php artisan cache:clear
php artisan route:clear
php artisan config:clear
php artisan view:clear

2. Ensure the app is doing the right thing using Log::info('your message here') in the method of switching language and in the middleware. (File is located in storage/logs/laravel.log)

// Controller:
public function SwitchLang(Request $request)
{
        Log::info('Switching to locale: ' . $request->lang);
}

--

// Middleware:
public function handle(Request $request, Closure $next): Response
{
        if (session()->has('locale')) {
            App::setLocale(session()->get('locale'));
        }
        Log::info('Current locale in middleware: ' . App::getLocale());
        Log::info('Session locale in middleware: ' . session()->get('locale'));
}

3. After checking logs you will see if there is any missmatch for example, in my app the middleware was not accessing correctly the session, so to fix that i had to add the middleware in bootstrap/app.php in the withMiddleware part but assign it to group Web.

->withMiddleware(function (Middleware $middleware) {
        $middleware->appendToGroup('web', LanguageSwitcher::class);
    })

Hope it helps anyone.

abkrim's avatar
Level 13

@pmeneses97 read my comment two months ago. Problem already solved. Thanks for the class.

Please or to participate in this conversation.