UI strings
Designed for any JS/TS project that uses i18next: React apps, Next.js (client and server components), Node.js services, Plain HTML, Astro websites and CLI tools.
Which guide to read
| Your app | Read next |
|---|---|
| React / Next.js / Node + i18next | Wire i18next (Step 4) |
Plain HTML (no t() in markup) | Plain HTML apps |
| Astro marketing site (hybrid) | Astro website |
t() rules, interpolation, plurals | t() calls & plurals |
| Language picker / RTL | Language switcher & RTL |
| Runtime API signatures | Runtime helpers |
Step 1: Initialise
ai-i18n-tools init [-P <provider>]This writes ai-i18n-tools.config.json with the ui-markdown template (including a default provider / providers block). Before running translate-ui or sync, set the API key for your active provider in the environment or .env — Ollama excepted; see Provider and API key. Edit the config to set:
providerandproviders— at least one provider withtranslationModels; change the preset or model list if the default is not your choice (init -P <provider>). See LLM providers and models.sourceLocale- your source language BCP-47 code (e.g."en-GB"). Must matchSOURCE_LOCALEexported from your runtime i18n setup file (src/i18n.ts/src/i18n.js).targetLocales- array of BCP-47 codes for your target languages (e.g.["de", "fr", "pt-BR"]). Rungenerate-ui-languagesto create theui-languages.jsonmanifest from this list.ui.sourceRoots- directories or glob patterns to scan fort("…")calls (e.g.["src/"],["src/**/*.ts"]).ui.stringsJson- where to write the master catalog (e.g."src/locales/strings.json").ui.flatOutputDir- where to writede.json,pt-BR.json, etc. (e.g."src/locales/").providers.<active>.uiModels(optional) - ordered UI-only model list fortranslate-ui, plural generation, andproofread-ui(after any matchinglocaleModelsentry, beforetranslationModels). See Providers and models.
Step 2: Extract strings
ai-i18n-tools extractScans all JS/TS files under ui.sourceRoots for t("literal") and i18n.t("literal") calls. Writes (or merges into) ui.stringsJson.
The scanner is configurable: add custom function names via ui.uiExtractor.funcNames (or legacy ui.reactExtractor.funcNames). For Astro pages and components, add .astro to ui.uiExtractor.extensions. For plain HTML, see Plain HTML apps.
Step 3: Translate UI strings
ai-i18n-tools translate-uiReads strings.json, sends batches to the active LLM provider for each target locale, writes flat JSON files (de.json, fr.json, etc.) to ui.flatOutputDir. Model selection uses the UI chain: localeModels(locale) → uiModels → translationModels (see Providers and models).
Per-locale model overrides
Depending on the target language, some translation models may perform significantly better than others—for example, qwen and z-ai models tend to produce higher quality translations for Asian languages compared to many Western (Occidental) language models. To take advantage of this, you can use optional providers.<active>.localeModels entries to specify a prioritized list of models for each BCP-47 locale. These model lists are tried before the more general uiModels and translationModels for that particular locale. This allows you to tailor model selection and achieve better translation quality per language. Locale tags are matched case-insensitively (so zh-cn and ZH-CN are equivalent). If no custom entry matches a locale, the tool falls back to the default uiModels and translationModels order for UI translations. The same localeModels mechanism also applies to document, JSON, and SVG translation.
Translations database (strings.json)
For each entry, translate-ui stores the model id from the active provider that successfully translated each locale in an optional models object (same locale keys as translated). Strings edited in the Translation Dashboard are marked with the sentinel value user-edited in models for that locale. The per-locale flat files under ui.flatOutputDir remain source string → translation only; they do not include models (so runtime bundles stay unchanged).
Note: Dashboard edits to UI strings live in
strings.json, not the SQLite documentation cache. Run plainsyncortranslate-ui(no special flag) to rewrite flat locale files from the catalog —--force-updateis not forwarded to the UI step. Avoid--forceon UI commands after manual edits: it re-translates every entry and can overwrite youruser-editedrows.
Then wire i18next at runtime — Wire i18next.
Exporting to XLIFF 2.0 (optional)
To hand UI strings off to a translation vendor, TMS, or CAT tool, export the catalog as XLIFF 2.0 (one file per target locale). This command is read-only: it does not modify strings.json or call any API.
ai-i18n-tools export-ui-xliffBy default, files are written next to ui.stringsJson, named like strings.de.xliff, strings.pt-BR.xliff (basename of your catalog + locale + .xliff). Use -o / --output-dir to write elsewhere. Existing translations from strings.json appear in <target>; missing locales use state="initial" with no <target> so tools can fill them in. Use --untranslated-only to export only units that still need a translation for each locale (useful for vendor batches). --dry-run prints paths without writing files.