Alexis P.
Alexis P.

Reputation: 35

Laravel App defaults to fallback_locale when trying to switch language

I'm trying ( for the first time) to build a system to change the language on my web app with a menu selection. For the purpose of testing i'm trying with 2 languages, french, and english.

I've built my app with Laravel 10, so i've followed the Laravel doc for the setup : I have a lang folder in my resources folder, inside of which i have a en and an fr folder, each with a messages.php to house the keys.

I've checked my app.php, my kernel.php, made a SetLocale Middleware, and a LanguageChange controller. In order to illustrate my problems here is some of the code :

SetLocale Middleware is as follow :

<?php

 namespace App\Http\Middleware;

 use Closure;
 USE illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\App;
 use Illuminate\Support\Facades\Request;

 class SetLocale
 {
    public function handle($request, Closure $next)
    {
        $language = session('locale', config('app.fallback_locale'));
        Log::info('Session locale: ' . session('locale'));
        App::setLocale($language);
        Log::info('Selected locale: ' . $language);
        return $next($request);
    }

 }

the LanguageChange Controller is as follows :

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\App; // Add this line
use Illuminate\Http\Request;

class LanguageController extends Controller
{
    public function changeLanguage(Request $request, $locale)

    {
        // Log the current session 'locale' value


        $request->session()->put('locale', $locale);
        // Log the current session 'locale' value
        Log::info('Session locale: ' . session('locale'));
        $language = session('locale', config('app.fallback_locale'));
        App::setLocale($language);

        session(['locale' => $locale]);
        return redirect()->back();
    }



}

As i previously mentionned, i've set my app locale as fr, and my fallback as en alongside my available.locales as both en and fr.

This is the element i'm doing my testing with :

            <form method="POST" action="{{ route('change.language', 'en') }}">
                @csrf
                <button type="submit">Change to English</button>
            </form>

            <form method="POST" action="{{ route('change.language', 'fr') }}">
                @csrf
                <button type="submit">Change to French</button>
            </form>
            <div class="TextPresentation">
                <h2>{{__('messages.welcome')}}</h2>

                <p> {{__('messages.description')}}</p>
                <br/>
                <br/>
                <p>{{__('messages.contact')}}
                </p><a href="#">{{__('messages.Malt')}}</a>,<a href="#">{{__('messages.Fiverr')}}</a>
            </div>

Finally, the route for the form action :

Route::match(['get','post'], '/change-language/{locale}', [LanguageController::class, 'changeLanguage'])->name('change.language');

A form to have 2 buttons to change the language, and a block of text for which the elements call the keys of the lang folder. When changed manually ( or to be precise when i change the fallback_locale manually) the translation is done, showing me two things : 1)The lang files are accessed since the keys call the correct text based on the language of the fallback_locale 2)Something seems to force the app the default to the fallback_locale.

I'm not sure how to figure out what causes it. I've used the log method to see what happens and it shows the following :

[2023-09-19 22:01:00] local.INFO: Session locale:   
[2023-09-19 22:01:00] local.INFO: Selected locale: fr  
[2023-09-19 22:01:00] local.INFO: Session locale: fr  
[2023-09-19 22:01:00] local.INFO: Session locale:   
[2023-09-19 22:01:00] local.INFO: Selected locale: fr  

(This is a single press of one of the form button) session locale seems to never be set correctly. And the Selected locale always matches the fallback_locale of the app.

I'm not exactly sure how to diagnose and debug the issue. I initially tried to make the page dynamically change its language based on browser preference settings, and it worked. But when i try to make it so the user has agency by selecting a language, i'm now facing this issue ...

I'd appreciate any help/suggestions ;-;

Upvotes: 0

Views: 648

Answers (1)

Abdulla Nilam
Abdulla Nilam

Reputation: 38609

Change your route to

Route::get('/change-language', [LanguageController::class, 'changeLanguage'])->name('changeLang');

In Blade, use this for a language switch. (using AJAX, you can use simple HTTP as well. You can find answers on Google as well.)

 <select class="form-control changeLang">
      <option value="en" {{ session()->get('locale') == 'en' ? 'selected' : '' }}>English</option>
      <option value="fr" {{ session()->get('locale') == 'fr' ? 'selected' : '' }}>France</option>
 </select>

<script type="text/javascript">
  
    var url = "{{ route('changeLang') }}";
  
    $(".changeLang").change(function(){
        window.location.href = url + "?lang="+ $(this).val();
    });
  
</script>

In Controller

 public function changeLanguage(Request $request, $locale) {

      App::setLocale($request->lang);
      session()->put('locale', $request->lang);

      return redirect()->back();
 }

In Middleware (use this), use a filename like LanguageSwitch

public function handle($request, Closure $next)
{
    if (session()->has('locale')) {
        App::setLocale(session()->get('locale'));
    }
      
    return $next($request);
}

Upvotes: 0

Related Questions