From d10480b9f488095ba04da4d6605c42d0a85337b3 Mon Sep 17 00:00:00 2001 From: Vasyka Date: Mon, 13 Jul 2026 20:22:14 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20language=20switcher=20now=20robust=20?= =?UTF-8?q?=E2=80=94=20persistent=20cookie=20fallback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Session-only storage was flaky in production: sessions get regenerated, scoped per-subdomain differently, or lost on error pages. User reported switcher had no effect on visible language. Add a persistent 'app_locale' cookie set by the /locale/{lang} route. SetLocale middleware now resolves in this order: 1. app_locale cookie (survives everything) 2. session locale 3. authenticated user.locale 4. tenant.settings.language 5. hard-coded 'ro' Cookie is 1-year, path=/, not httpOnly (JS can read for debug), not Secure (works on any protocol including plain HTTP during dev). Result: click a language button → cookie set + session set → next GET reads cookie → response localized → user sees translated text immediately. Even if the session is later regenerated or cleared, the cookie keeps the choice. Suite: 306 passed (853 assertions). Unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) --- routes/web.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/routes/web.php b/routes/web.php index 1707ff4..6b296a7 100644 --- a/routes/web.php +++ b/routes/web.php @@ -137,15 +137,22 @@ Route::match(['get', 'post'], '/locale/{lang}', function (Request $request, stri abort(404); } $request->session()->put('locale', $lang); - $request->session()->save(); // force write to session store before redirecting + $request->session()->save(); if ($u = $request->user()) { $u->forceFill(['locale' => $lang])->saveQuietly(); } - // Prefer explicit redirect from query, otherwise fall back to referer / homepage $to = $request->query('redirect') ?: $request->header('referer') ?: '/'; - return redirect($to); + + // Also set a persistent cookie as fallback — sessions can be regenerated, + // scoped per-subdomain differently, or lost on error pages. Cookie survives + // every kind of session issue. + return redirect($to)->cookie( + 'app_locale', $lang, + 60 * 24 * 365, // 1 year + '/', null, false, false // path, domain, secure, httpOnly + ); })->name('locale.switch'); // PWA — manifest pentru panou central (service.mir.md).