A small Dart command-line tool that generates translations for ARB files (Flutter/Intl) via OpenAI and saves them as separate ARB files per target language.
- Reads a template ARB from a configured directory.
- Translates only the actual string values (no
@metadata). - Preserves ICU placeholders like
{count},{name},{total}exactly. - Writes a separate ARB file per target locale.
- Optional dry run, targeted locale selection, selectable OpenAI model.
- Dart SDK installed (2.19+ recommended).
- OpenAI API key as environment variable:
- macOS/Linux:
export OPENAI_API_KEY="sk-..." - Windows (PowerShell):
$Env:OPENAI_API_KEY="sk-..."
- macOS/Linux:
- ARB template file with valid JSON.
- Resolve dependencies:
dart pub get
- Optional: Build binary:
dart compile exe bin/<entrypoint>.dart -o build/l10n-translator
Note: The entry point is located in the bin/ directory. Replace <entrypoint>.dart with the actual file name.
Create an l10n.yaml in the project, for example:
yaml
yaml arb-dir: lib/l10n # Directory with ARB files template-arb-file: app_de.arb # Template ARB (source language)
output-localization-file: app_localizations.dart # not modified here, but commonly present in Flutter setups
locales: en, fr, es # Target languages (comma-separated)
arb-dir: Folder containing the ARB files.template-arb-file: The source template (e.g.app_de.arb).output-localization-file: Not written by this tool, but commonly used by Flutter tooling.locales: List of target locales as a comma-separated string. Can be overridden via CLI.
- Translatable entries are plain string values. ARB metadata such as keys starting with
@are not translated. - Placeholders in ICU format (e.g.
{name},{count}) must be correctly present in the template and are carried over as-is. - Emojis, ellipsis characters (...) and line breaks (
\n) are preserved.
General:
dart run bin/<entrypoint>.dart [options]
Options:
-c, --config <path>: Path tol10n.yaml(default:l10n.yaml)--source-locale <code>: Source language of the template (default:de)--model <name>: OpenAI model (default:gpt-4o-mini)--dry-run: Write nothing, only display--only <locale>: Translate only these target locales; can be specified multiple times (overrideslocalesfroml10n.yaml)
Examples:
- Standard run with
l10n.yaml:dart run bin/<entrypoint>.dart
- English and French only:
dart run bin/<entrypoint>.dart --only en --only fr
- Dry run (shows what would be written):
dart run bin/<entrypoint>.dart --dry-run
- Different config file and model:
dart run bin/<entrypoint>.dart -c config/l10n.yaml --model gpt-4o-mini
- For each target locale, a corresponding target name is derived from the template file name, e.g.:
- Template
app_de.arb-> Targetapp_en.arb,app_fr.arb, ...
- Template
- The
@@localefield is set to the target locale in the result. - With
--dry-run, no files are written.
- "Missing environment variable OPENAI_API_KEY.": Set the API key in your shell environment.
- "l10n.yaml not found" or "ARB directory not found": Check paths in
--configandl10n.yaml. - HTTP errors from OpenAI (4xx/5xx): Check API key, model name, quota/rate limits, network.
- "Placeholder mismatch": Ensure that placeholders in all strings are correct and are not altered in the translation.
- Contents of ARB strings are sent to the OpenAI API. Check internal policies and remove sensitive data.
- Costs may apply depending on the model and data volume.
MIT