From d132efd86153fb295b525b55cf4a32ce01cf4c8d Mon Sep 17 00:00:00 2001 From: boban Date: Sun, 14 Jun 2026 15:32:20 +0200 Subject: [PATCH] fix(i18n): localize error pages thrown before SetLocale middleware MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- app/Http/Middleware/SetLocale.php | 26 +++++++++++++++++++++----- bootstrap/app.php | 11 +++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/app/Http/Middleware/SetLocale.php b/app/Http/Middleware/SetLocale.php index 2242bbf..131df53 100644 --- a/app/Http/Middleware/SetLocale.php +++ b/app/Http/Middleware/SetLocale.php @@ -18,14 +18,30 @@ class SetLocale public function handle(Request $request, Closure $next): Response { - $locale = $request->user()?->locale - ?? $request->session()->get('locale') - ?? config('app.locale'); + 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') + ?? $locale; + } if (in_array($locale, self::SUPPORTED, true)) { app()->setLocale($locale); } - - return $next($request); } } diff --git a/bootstrap/app.php b/bootstrap/app.php index f56377f..912fa3f 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -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();