/** * EnCoach i18n bootstrap. * * We keep the translation strings in TypeScript modules (one per locale) so * they go through type-checking and tree-shaking, and so non-translators * can't ship a broken JSON file that blocks the build. * * Language selection order (product decision: English is the default UI * language at startup; Arabic is opt-in via the language toggle): * 1. localStorage key ``encoach-lang`` (explicit user pick, persisted) * 2. ``en`` — fallback used on first visit, regardless of browser locale * * We intentionally do **not** read ``navigator.language`` anymore: an * Arabic-locale browser should still land on the English UI the first time * a user visits, because the QA team and the product manager both sign off * against the English baseline. Users that actively want Arabic flip the * toggle once and the preference is remembered from then on. * * RTL handling: whenever the active language switches to one of RTL_LANGS, * we flip ``document.documentElement.dir`` so Tailwind's RTL utilities + * Radix primitives pick up the change automatically. */ import i18n from "i18next"; import LanguageDetector from "i18next-browser-languagedetector"; import { initReactI18next } from "react-i18next"; import ar from "./locales/ar"; import en from "./locales/en"; const RTL_LANGS = new Set(["ar", "he", "fa", "ur"]); export const SUPPORTED_LANGS = [ { code: "en", label: "English" }, { code: "ar", label: "العربية" }, ] as const; export type SupportedLang = (typeof SUPPORTED_LANGS)[number]["code"]; export const DEFAULT_LANG: SupportedLang = "en"; i18n .use(LanguageDetector) .use(initReactI18next) .init({ resources: { en: { translation: en }, ar: { translation: ar }, }, // Explicit default — english is the baseline UI language at startup. lng: DEFAULT_LANG, fallbackLng: DEFAULT_LANG, supportedLngs: SUPPORTED_LANGS.map((l) => l.code), interpolation: { escapeValue: false }, detection: { // Only honour the user's saved pick. Navigator/htmlTag detection was // removed so Arabic-locale browsers don't silently boot the UI in // Arabic before the user has chosen. order: ["localStorage"], caches: ["localStorage"], lookupLocalStorage: "encoach-lang", }, returnEmptyString: false, }); export function applyDirectionForLang(lang: string) { const base = lang.split("-")[0]; const dir = RTL_LANGS.has(base) ? "rtl" : "ltr"; if (typeof document !== "undefined") { document.documentElement.dir = dir; document.documentElement.lang = base; } } if (typeof window !== "undefined") { applyDirectionForLang(i18n.language || "en"); i18n.on("languageChanged", applyDirectionForLang); } export default i18n;