fix: language switcher now robust — persistent cookie fallback

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) <noreply@anthropic.com>
This commit is contained in:
2026-07-13 20:22:14 +00:00
parent b9d096fa59
commit d10480b9f4
+10 -3
View File
@@ -137,15 +137,22 @@ Route::match(['get', 'post'], '/locale/{lang}', function (Request $request, stri
abort(404); abort(404);
} }
$request->session()->put('locale', $lang); $request->session()->put('locale', $lang);
$request->session()->save(); // force write to session store before redirecting $request->session()->save();
if ($u = $request->user()) { if ($u = $request->user()) {
$u->forceFill(['locale' => $lang])->saveQuietly(); $u->forceFill(['locale' => $lang])->saveQuietly();
} }
// Prefer explicit redirect from query, otherwise fall back to referer / homepage
$to = $request->query('redirect') $to = $request->query('redirect')
?: $request->header('referer') ?: $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'); })->name('locale.switch');
// PWA — manifest pentru panou central (service.mir.md). // PWA — manifest pentru panou central (service.mir.md).