#Internationalization
#Rules (project + product)
- Every URL has a locale segment:
/en/dashboard,/de/dashboard. Confirmed project rule - All UI text comes from translation files (
messages/<locale>.json). No hard-coded English in components. Confirmed - English is the source: add the key to
messages/en.jsonfirst. Other locales fall back to English until translated. - Locales: en (default), es, de, fr, pt, ja, ru, hi, all left-to-right. Same set as the OSS panel's
locales_available. Confirmed OSS API - Numbers, money, dates, relative times through next-intl (
useFormatter,<FormattedX/>). NevertoLocaleString().
#URL handling
RequestURL has /{locale}?Yes → use it (if supported)No → cookie NEXT_LOCALEAccept-Languagedefault enredirect to /{locale}/path
- Unsupported locale in the URL (
/xx/dashboard) → 404 page in the default locale Assumption (or redirect to/en/...). - The language switcher swaps the segment and keeps the rest of the path and query, sets the cookie, and (once the profile has a language field) saves it to the profile Missing.
<html lang>follows the locale.
#Backend messages
- Send
Accept-Language: <locale>on every API call, so Laravel validation and error messages come back translated (V8 R3 + the OSS pattern). Assumption sa-central-api-2 must support it Missing. - Forward the same header to OSS. OSS already localises its
messagefields. OSS API - Prefer codes in API errors (
code: "PLAN_LIMIT_REACHED") mapped to frontend keys, with the backendmessageas a fallback. - Audit and notification entries carry
action/typekeys + params, so they render in the viewer's language (V7 stored English sentences).
#Missing translations
- In development: log a warning naming the missing key, and render the English text.
- In production: silent fallback to English, no raw key shown.
- CI check: every key in
en.jsonexists in each locale file (allowed to equal English), and there are no unused keys Assumption.
#Content not translated
User data (server names, organization names, member names), raw OSS output (logs, command output), and plan names unless the API provides translations Open question.