@key metadata in the repository, review ICU in Platform, then run flutter gen-l10n on the approved files.
hl extract does not scan Dart AppLocalizations calls. Treat lib/l10n/app_en.arb as the source of truth.
Prerequisites
You need:- a Flutter app with
gen-l10nenabled; - the Hyperlocalise CLI;
- a Platform project with
enas source andfranddeas targets; and HYPERLOCALISE_API_KEYandHYPERLOCALISE_PROJECT_IDin your environment.
en_US or fr_FR files, set i18n.yml locales to the exact suffix in those names. {{target}} is written as configured, so fr-FR produces app_fr-FR.arb, not app_fr_FR.arb.
1. Keep copy in ARB
l10n.yaml:
lib/l10n/app_en.arb:
savedFiltersTitle. Keys that start with @, including @@locale and @savedFiltersTitle, stay metadata. Writeback copies source metadata onto new messages and sets @@locale to the target locale.
Do not set the file’s message format to i18next. Flutter ARB uses ICU
{name} and {count, plural, …}. Leave the format on Auto or ICU.2. Map the catalogs
Createi18n.yml:
3. Catch missing keys in the source pull request
Generate localizations, then compile:app_en.arb with the widget change. A missing ARB key fails the Dart build when the widget calls a getter that gen-l10n did not emit.
4. Push and review
After the source pull request merges:- ICU arguments such as
{name}and{count}; - plural and select branches, including locale-specific categories;
@keydescriptions that explain where the string appears;- labels that must fit compact mobile layouts.
one and keep other. hl check reports unreachable_plural_case when a translation keeps a category the locale never selects.
5. Pull and validate translations
Run:hl check reports missing target keys, placeholder mismatches, icu_shape_mismatch, and unreachable_plural_case. Then change the device or test locale and confirm AppLocalizations loads app_fr.arb and app_de.arb.
Open a translation pull request containing the pulled ARB files and any regenerated Dart output your repo commits.
Troubleshooting
flutter gen-l10n ignores a pulled file
The filename suffix must match a locale Flutter accepts. Compare the resolved to path from hl sync pull --dry-run with arb-dir. Hyphenated locales in i18n.yml do not become underscored Flutter names.
Content Editor shows no description
Put the explanation on@message.description, not in a JSON comment. ARB comments are not catalog context.
Pull rewrites @ objects
That means a message value was stored under a metadata key. Message keys must not start with @.
icu_shape_mismatch after a locale-specific plural
Argument names, block types, offsets, and exact matches such as =0 must still match the source. CLDR categories may differ by locale. If hl check reports unreachable_plural_case, delete the unused case from the translation.

