# @wrnexus/i18n Recursive locale loading, fallback resolution, SSR/browser translations, locale formatting, and language UI blocks for WRNexusJS. ## Locale files Both layouts can be used together: ```text app/locales/en.json app/locales/en/common.json app/locales/en/auth.json app/locales/mr/common.json ``` Namespaced files become keys such as `common.save` and `auth.signIn`. ```ts import { loadLocales, makeT, resolveI18n, resolveLang } from "@wrnexus/i18n"; const i18n = resolveI18n(loadLocales("app/locales", { strict: true }), { default: "en", locales: ["en", "mr", "hi"], fallbacks: { "mr-IN": ["mr", "en"] }, cookie: { name: "wire-lang", sameSite: "Lax", secure: true }, }); const lang = resolveLang(i18n, cookieValue, request.headers.get("accept-language")); const t = makeT(i18n, lang); t("common.hello", { name: "Ajay" }); ``` ## Resolution behavior - normalized BCP-47-style locale names - cookie preference - weighted `Accept-Language` - wildcard language ranges - regional base fallback - explicit fallback chains - configured default language - automatic RTL for Arabic, Hebrew, Persian, Urdu, and related languages Locale JSON is size-limited and rejects prototype-pollution keys. Recursive namespace collisions are resolved safely. ## Views and runtime ```html

Dashboard

``` Text and translated attributes are resolved during SSR. Active/fallback messages are serialized safely for the language runtime, which rebinds `data-t` markers after client navigation. Enable `i18nPlugin()` to use: - `` - `` `LanguageSwitcher` renders a native `select[data-wire-lang]`. The packaged runtime validates the selection against the configured locales, writes the configured language cookie, updates the document `lang`/`dir` attributes, emits `wrnexus:language-change`, and reloads so the next SSR request uses the same cookie. No application-owned browser script is required. ## Formatting - `formatNumber` - `formatCurrency` - `formatDate` - `formatRelativeTime` - `plural` - `createLocaleFormatter` - `translationCoverage` Localization tooling can extract statically discoverable `t("key")`, `i18n.t("key")`, and `data-i18n="key"` usage, compare every locale with a reference, and create layout-stressing pseudo-locales: ```ts import { auditLocaleKeys, createPseudoLocale, extractTranslationKeysFromFiles, } from "@wrnexus/i18n"; const used = extractTranslationKeysFromFiles(sourceFiles); const coverage = auditLocaleKeys(messages, "en"); const enXA = createPseudoLocale(messages.en); const arXB = createPseudoLocale(messages.en, { rtl: true }); ``` Pseudo-localization preserves interpolation placeholders and markup tags. RTL pseudo output uses Unicode direction controls, while runtime direction detection continues to derive `rtl` from Arabic and other RTL language subtags.