Sdílená i18n cookie přebije jazyk tenant back-office
import { Aside } from ‘@astrojs/starlight/components’;
Symptom
Sekce “Symptom”Multi-tenant aplikace s jedním veřejným webem (jeden hostname, přepínač jazyků) a privátním back-office pro tenanty. Zahraniční tenant má v profilu nastaven svůj jazyk (např. en), ale jeho admin rozhraní se zobrazí v jazyce webu (např. cs) — protože si předtím prohlížel veřejný web a ten mu nastavil jazykovou cookie. Lokalizace stránky je technicky hotová, a přesto se vykreslí špatný jazyk.
Root cause
Sekce “Root cause”Sdílený jazykový middleware řeší jazyk podle priority, kde cookie je výš než profil:
?lang param > URL prefix > cookie > profil uživatele > Accept-Language > defaultStránka back-office pak čte locals.lang, který už je „znečištěný” globální cookie z veřejného webu:
// ❌ back-office bere site-wide jazykconst L = locals.lang === 'cs' ? 'cs' : 'en';Cookie je správná pro veřejný web (návštěvník si zvolil jazyk), ale back-office tenanta musí být deterministicky v jazyce tenanta, nezávisle na tom, co si uživatel klikl na veřejné části.
Fix
Sekce “Fix”Back-office si jazyk odvodí přímo z profilu tenanta (= jazyk nastavený při registraci), ne z locals.lang:
// ✅ back-office se zamkne na jazyk tenantaconst L = locals.profile?.language === 'cs' ? 'cs' : 'en';const t = DICT[L];Ověření (curl s vynucenou opačnou cookie):
- tenant
en+lang-cookie=cs→ back-office anglicky ✓ - tenant
cs+lang-cookie=en→ back-office česky ✓
Veřejný web dál respektuje cookie; jen privátní back-office ji ignoruje.
Jak se tomu vyvarovat v jiných systémech
Sekce “Jak se tomu vyvarovat v jiných systémech”- Detection: v back-office/admin šablonách grepni použití globálního
locals.lang/i18n.locale/ jazykové cookie. Code-review otázka: „čte tahle privátní stránka jazyk ze sdílené cookie?” - Anti-pattern: jeden globální
resolveLanguage()se stejnou prioritou pro veřejné i privátní routy. Cookie nastavená na veřejné části tiše ovlivní admin. - Lepší přístup: dvě úrovně jazyka — site language (cookie/URL, pro návštěvníky) vs actor language (z DB profilu, pro přihlášené role). Back-office, e-maily a faktury tenanta vždy z profilu/entity, ne z prezentační cookie.
Sister bugs / související
Sekce “Sister bugs / související”Stejná past hrozí u transakčních e-mailů a PDF faktur — pokud je generuješ v „aktuálním jazyce požadavku” místo v jazyce příjemce uloženém u entity, pošleš zákazníkovi dokument v cizím jazyce.