Regional languages
Use region and script codes such as en-US, pt-BR or zh-Hant, let them inherit text from their base language, and change a code without losing translations.
On this page
Language codes
A language code is a language of 2 to 8 letters, optionally followed by a 4-letter script and a 2-letter or 3-digit region, separated by - or _. For example: en, en-US, pt_BR, zh-Hant, sr-Latn-RS or es-419. ReRune rejects new codes in other shapes, such as en US or ca-ES-valencia, because the SDKs can't deliver them.
Codes that differ only in case or separator, such as en-US and en_us, are the same language, so a project can contain only one of them. Codes that were added before these rules keep working as they are.
Prefer the standard form
Write codes as en-US, pt-BR and zh-Hant. ReRune writes each platform's own form in files, so the stored code doesn't have to match a file name.
How regional languages inherit text
A regional or script language inherits from the nearest project language without its region or script: de-AT from de, zh-Hant-TW from zh-Hant and then zh, sr-Latn-RS from sr-Latn and then sr. The main language never inherits.
When a key has no text in de-AT, the editor shows the German text with a hint, and the key list shows it greyed out. Inherited text counts as done for completion, the missing-translation filter and publish warnings, and the completion chart shows how much of a language is inherited. Type in the field to give de-AT its own text.
Apps follow the same chain at runtime. The Flutter SDK looks for de_AT, then de, then the main language for every key, so you only need to translate the words that differ. Exported files and OTA bundles contain only a language's own text. Android, iOS, Flutter, Java and gettext fall back to the base language file themselves.
File names per platform
When you export files or pull them with the CLI, ReRune writes each code in the platform's own form. When you import a file, it maps the file's locale back to the project language. Base codes such as en or de are written as before.
| Platform | pt-BR | sr-Latn-RS |
|---|---|---|
| Android | values-pt-rBR | values-b+sr+Latn+RS |
| iOS | pt-BR.lproj | sr-Latn-RS.lproj |
| Flutter | app_pt_BR.arb | app_sr_Latn_RS.arb |
| Java, Qt, Symfony | messages_pt_BR.properties | messages_sr_Latn_RS.properties |
| gettext, WordPress | pt_BR.po | sr_RS@latin.po |
| Laravel | pt_br.php | sr_latn_rs.php |
| .NET (RESX, RESW) | Resources.pt-br.resx | Resources.sr-latn-rs.resx |
| i18next, Vue, Rails, JSON, XLIFF | pt-BR.json | sr-Latn-RS.json |
Flutter base language files
Flutter's gen-l10n only builds when every regional or script ARB file has a file for its bare language: app_pt_BR.arb needs app_pt.arb. When the project has pt-BR but no pt, rerune pull (CLI 1.0.19 or newer) creates app_pt.arb containing only its @@locale, and downloads of all languages include it. ReRune never overwrites an existing file, never adds it to rerune.json and never pushes it. Flutter fills its messages from the main language.
Machine translation
DeepL receives its own variant when one exists: EN-US, EN-GB, PT-BR, PT-PT, ZH-HANS, ZH-HANT and ES-419, which also covers Spanish regions in Latin America. Otherwise it receives the base language. Bare codes such as en and pt are sent as before.
DeepL skips a target in the source's own language, such as en-US to en-GB. It also skips a regional language without its own DeepL variant when a language it inherits from is in the project, such as de-AT when the project has de. Choosing that one language explicitly returns an error that says so. Other DeepL failures are shown as DeepL errors.
AI translation receives each language's name, such as German (Austria), and writes in the regional variant's spelling and vocabulary. When it translates missing text for all languages, it skips languages that already inherit text. A regional language you choose explicitly is still translated.
Change a language code
To move a project from en to en-US, use Change code next to the language in project settings. ReRune moves the language's translations, published content, AI model choice and preview settings to the new code in one step, and apps download the language again under the new code. Publication history keeps the old code, and rollback still works.
Update rerune.json
After a rename, replace the old code in rerune.json. Until then, rerune push stops with a message that names the new code instead of adding the old language again. Files whose path contains the code are written to the new path on the next pull, and the old files stay on disk.
Renaming a base language
Renaming en to en-US means other English regions, such as en-GB, no longer fall back to English and use the main language instead. To keep English as the fallback, keep en and add en-US.