I was working on adding localization to my Laravel 11 project, and I created a middleware called SetLocale
that consists of the codebase similar to below:
public function handle(Request $request, Closure $next): Response
{
App::setLocale(session()->get('locale'));
return $next($request);
}
I added it to my bootstrap/app.php
file like this:
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__ . '/../routes/web.php',
commands: __DIR__ . '/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
$middleware->append(SetLocale::class);
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
In my LocalizationController, I set the session like this:
public function setLocalization(string $locale): RedirectResponse
{
session()->put('locale', $locale);
App::setLocale($locale);
return back();
}
My route in web.php
looks like this:
Route::get('/locale/{locale}', [LocalizationController::class, 'setLocalization'])->name('locale.switch');
Here's what I tried:
back()->with('locale', $locale);
when returning in the setLocalization()
function in the LocalizationController, but it didn't work.The only way I got it to work was by wrapping the middleware around the route like this:
Route::prefix('localization')->middleware([SetLocale::class])->group(function() {
Route::get('/locale/{locale}', [LocalizationController::class, 'setLocalization'])->name('locale.switch');
});
Is my use of global middleware incorrect, or did Laravel change how it handles sessions for global middleware?
Just an FYI, Laravel has now moved its middleware to elsewhere. Now it's a clean file located in the bootstrap/app.php file.
Thanks for your help.
To expand on the answer provided by @lagbox, the middleware that handles the session is defined as part of the web
route middleware group. It is not defined as a global middleware. As mentioned by @lagbox, the route middleware are run after the global middleware.
The append()
method you've used in your withMiddleware()
callback will append the provided middleware to the global middleware. This is not what you want, since your new appended global middleware will run before the session middleware defined in the web
route middleware group.
To get your desired result, you can use the appendToGroup()
method instead of the append()
method. This will append your middleware to the specified middleware group, instead of adding it as a global middleware.
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__ . '/../routes/web.php',
commands: __DIR__ . '/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
// Use appendToGroup() to add the middleware to the 'web' group.
$middleware->appendToGroup('web', SetLocale::class);
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With