fix(i18n): localize error pages thrown before SetLocale middleware

CSRF (419), unmatched-route 404 and maintenance (503) errors are thrown before
the web-group SetLocale middleware runs, so the custom error pages rendered in
the default locale for EN users. Extract SetLocale::apply() (session-guarded, so
it is safe pre-session) and call it from a withExceptions render hook that falls
through to the normal renderer — the error views now honour the user's language
where it is known.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat/v1-foundation
boban 2026-06-14 15:32:20 +02:00
parent c5d3de6e0b
commit d132efd861
2 changed files with 32 additions and 5 deletions

View File

@ -18,14 +18,30 @@ class SetLocale
public function handle(Request $request, Closure $next): Response
{
self::apply($request);
return $next($request);
}
/**
* Resolve + set the active locale: signed-in user's preference, then the session
* choice, then the app default. Safe to call before the session is started e.g.
* from the exception handler for errors thrown before this middleware (CSRF 419,
* unmatched-route 404, maintenance 503) a missing session is simply skipped, so
* those custom error pages still honour the user's language where it is known.
*/
public static function apply(Request $request): void
{
$locale = config('app.locale');
if ($request->hasSession()) {
$locale = $request->user()?->locale
?? $request->session()->get('locale')
?? config('app.locale');
?? $locale;
}
if (in_array($locale, self::SUPPORTED, true)) {
app()->setLocale($locale);
}
return $next($request);
}
}

View File

@ -42,4 +42,15 @@ return Application::configure(basePath: dirname(__DIR__))
$exceptions->shouldRenderJsonWhen(
fn (Request $request) => $request->is('api/*'),
);
// Errors thrown BEFORE the web-group SetLocale middleware (CSRF 419, an
// unmatched-route 404, maintenance 503) would render the custom error page in
// the default locale. Resolve the user's language first so those pages honour
// it too (R16); returning null falls through to the normal renderer (the
// resources/views/errors/* views).
$exceptions->render(function (Throwable $e, Request $request) {
SetLocale::apply($request);
return null;
});
})->create();