Locale resolution follows a deterministic precedence chain, rejects or normalizes untrusted locale tags from URLs and headers, and records the chosen locale for formatting without silently falling back to server default.
Package status: AI-assisted reference package. Static package validation has passed; implementation scenarios remain not run and human domain review is required before stable adoption.
Decision
The application resolves exactly one effective locale per request using a published precedence order. Untrusted inputs—URL parameters, anonymous headers, and third-party embeds—pass through BCP 47 validation and normalization before they can override stored user preferences. When no input is valid, the resolver walks supported locales and explicit fallback chains; it never silently applies server JVM default locale without recording an explicit unresolved outcome for telemetry. Users can see and override the effective locale where the product exposes language settings.
Scope
- Precedence among user saved preference, account locale, URL prefix, cookie, and Accept-Language.
- Tag validation, canonicalization, and unsupported-tag handling.
- Supported locale catalog with explicit fallback map.
- Persistence of effective locale on session or render context for formatting and translation lookup.
- Telemetry on unresolved or coerced locales.
Outside this block
- Translation management workflow and vendor TMS integration.
- RTL layout CSS architecture beyond locale flag exposure.
- Currency and timezone selection (separate blocks).
Contract
- Resolution order is fixed and documented; lower-priority sources cannot override higher unless explicitly allowed by profile.
- Malformed locale tags from untrusted sources are rejected, not coerced by truncation to arbitrary guesses.
- Unsupported but well-formed tags map through fallback table; if no mapping exists, resolver emits explicit unresolved code.
- Effective locale is recorded on render context and reused for date/number formatting in the same request.
- Changing URL locale prefix updates visible formatting on next navigation without requiring hidden server default.
- Accept-Language q-values are honored only after validation against supported catalog.
- Debug or staff impersonation cannot force unsupported locales in production profile.
Implementation guidance
- Normalize tags to canonical BCP 47 form before lookup.
- Keep supported locale list versioned configuration, not hard-coded scattered checks.
- Log coercion events with source input and resolved output for i18n QA.
Failure handling and safeguards
- If the catalog file fails to load, fall back deterministically to the configured profile default and alert; never inherit the process or JVM locale silently.
- Do not execute user-supplied locale strings in template paths or file loaders.
- Rate-limit locale-switch attempts that scan unsupported tags.
Verification and operations
- Monitor unresolved locale rate, coercion rate by source, and formatting mismatches in E2E checks.
- Test fallback chains whenever supported catalog changes.
- Execute acceptance scenarios in the target repository; packaged scenarios are not executed evidence.
Adoption assumptions
- Precedence and catalog entries in fixtures are profile choices.
- Teams map translation bundles and URL routing patterns locally.