Search code examples
phplaravellocalizationlaravel-9

I failed to localize validation error messages: they're still in English even when I pass a different locale to the request


I'm localizing validation error messages at the moment. I was trying to do it according to this article. There are no errors displayed, even though the article was published a long time ago, and Laravel 5 is used there, but the validation messages are still in English even when I pass a different locale to the request that switches languages. But when I change the locale in the app config (config/app.php) to 'ru', the messages are displayed in Russian. I don't understand what I am doing wrong. Here is the GitHub repo of this project, if you need it.

LanguageController.php:

<?php

namespace App\Http\Controllers;

use App\Http\Requests;
use Illuminate\Support\Facades\Config;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Session;

class LanguageController extends Controller
{
    public function switchLang(Request $request)
    {
        if (array_key_exists($request->userLocale, Config::get('languages'))) {
            Session::put('locale', $request->userLocale);
        } else {
            Session::put('locale', Config::get('app.fallback_locale'));
        }
        return Redirect::back();
    }
}

config/languages.php (I created this file):

<?php
return [
    'en' => 'English',
    'ru' => 'Русский',
];

My route:

Route::post("setLocale", [LanguageController::class, "switchLang"]);

Language.php middleware:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Session;

class Language
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle(Request $request, Closure $next)
    {
        if (
            Session::has('locale') &&
            array_key_exists(
                Session::get('locale'),
                Config::get('languages')
            )
        ) {
            App::setLocale(Session::get('locale'));
        } else {
            App::setLocale(Config::get('app.fallback_locale'));
        }
        return $next($request);
    }
}

Kernel.php:

protected $middlewareGroups = [
    // ...
    'api' => [
        // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        'throttle:api',
        \App\Http\Middleware\Language::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

Help is greatly appreciated. Thanks in advance! If you need something else to understand my question, feel free to ask!


Solution

  • The problem was that I use sessions, and Laravel API default setup doesn't include them. So, what did I do? I've added \Illuminate\Session\Middleware\StartSession::class to the api middleware group, just as @r1v3n said here, and it worked! Now I can switch locales. Thank you, everyone, and especially @paul-k, for leading me to this answer!