The CLI translates from one source locale into one or more target locales, both set in .lingo/config.json:
{
"sourceLocale": "en",
"targetLocales": ["de", "fr", "es", "ja"]
}Source files are read, never written. Each target locale gets its own output, with the locale code substituted into the file pattern (content/en/app.json → content/de/app.json). See Configuration.
Locale codes#
Use standard BCP 47 tags. A bare language code (de) or a language-region tag (de-CH) both work. The CLI doesn't keep a fixed list — targetLocales accepts any tag and passes it through to your engine. Which locales actually translate, and how well, is the engine's model range, not a CLI limit.
Common examples:
| Language | Code |
|---|---|
| English | en (or en-US, en-GB) |
| Spanish | es (or es-ES, es-419, es-MX) |
| French | fr (or fr-FR, fr-CA) |
| German | de (or de-CH, de-AT) |
| Portuguese | pt-BR, pt-PT |
| Chinese | zh-Hans, zh-Hant |
| Japanese | ja |
| Korean | ko |
Regional variants#
Pick a region when the dialect matters — the engine renders locale-appropriate spelling and vocabulary:
{
"sourceLocale": "en-US",
"targetLocales": ["en-GB", "es-ES", "es-419", "pt-BR", "pt-PT", "fr-CA"]
}en-US → en-GB turns "color" into "colour"; es-ES → es-419 swaps "ordenador" for "computadora". Quality of these distinctions comes from the engine's brand voice and instructions, not the CLI.
Right-to-left languages#
RTL locales (Arabic ar, Hebrew he, Persian fa, Urdu ur) translate like any other. Text direction in your app is your renderer's job; the CLI only produces the translated strings.
Adding or removing a locale#
Editing targetLocales is the whole change. To fill in a newly added locale, run lingo push --backfill-missing — see Adding a locale. To drop one, remove it and delete its files with lingo purge --locale.
