# Module: `src/i18n/i18n.ts` > **Source**: `src/i18n/i18n.ts` (13 lines) > **Topo batch**: B2 (depends only on JSON data files) ## Purpose Module-load-time initialisation of `i18next` with the `react-i18next` adapter. Imports the English and Ukrainian translation tables and registers them as the available `resources`. Exporting the configured singleton lets call sites use `useTranslation()` directly. ## Public interface ```ts export default i18n // configured i18next instance ``` ## Internal logic ```ts i18n.use(initReactI18next).init({ resources: { en: { translation: en }, ua: { translation: ua } }, lng: 'en', fallbackLng: 'en', interpolation: { escapeValue: false }, }) ``` - `lng: 'en'` is hardcoded at boot. There is **no** runtime mechanism to detect the user's locale or to read a saved preference. Switching language at runtime works (via `i18n.changeLanguage(...)`) but the page reload always lands on English first. - `escapeValue: false` is the documented default for React (which already escapes JSX text). - Module side-effect at top level: `init()` runs as soon as `src/main.tsx` imports this file. ## Dependencies - **Internal**: `./en.json`, `./ua.json` (JSON imports — Vite handles). - **External**: `i18next`, `react-i18next`. ## Consumers (intra-repo) - `src/main.tsx` — side-effect import (`import './i18n/i18n'`). - Indirectly: every component that calls `useTranslation()` from `react-i18next` (e.g. `ConfirmDialog`, `HelpModal`, `JsonEditorDialog`, …). ## Data models The two JSON resource files (`en.json`, `ua.json`) define the key namespace. Per `_docs/ui_design/README.md` §"Localization" and `_docs/legacy/wpf-era.md` §10, the SPA must support EN + UA at parity. Inspection of the JSON files (deferred to Step 4 verification) will confirm whether parity is held. ## Configuration `lng: 'en'` and `fallbackLng: 'en'` are inlined. `localStorage` persistence (e.g., via `i18next-browser-languagedetector`) would be the natural Step 8 enhancement for "remember user choice"; deferred. ## External integrations None. ## Security `escapeValue: false` is correct in React but would be unsafe if any consumer rendered translation values via `dangerouslySetInnerHTML`. None do (verify in Step 4). ## Tests None. ## Notes / open questions - The `mission-planner/` sub-project does NOT use `react-i18next` — it has its own `LanguageContext` + raw `translations` table (see `00_discovery.md` §11 finding 8). The port to `src/features/flights/` should consume this module instead. Track for MP-B3. - Adding a third language is a one-line edit (`resources: { en, ua, }`) plus a JSON file. Document the procedure in the final `solution.md`.