Prerequisites
You need:- a React app using
react-intl; - the Hyperlocalise CLI;
- a Cloud project with
en-USas source andfr-FRandde-DEas targets; and HYPERLOCALISE_API_KEYandHYPERLOCALISE_PROJECT_IDin your environment.
1. Define stable messages
Keep user-facing copy in descriptors with explicit IDs and translator descriptions:count argument and valid plural syntax.
2. Map the catalogs
Createi18n.yml:
defaultMessage and preserves message IDs, descriptions, and other metadata.
3. Extract the source catalog
Run:lang/en-US.json with the code change. This makes catalog drift visible in pull requests and gives Cloud a file to sync.
If you omit an
id, hl extract generates a FormatJS-compatible hash. Explicit IDs produce easier diffs and more recognizable entries in review.4. Prevent extract drift in CI
Re-run extraction in the source pull request and fail when it changes the committed catalog:defaultMessage without an updated catalog. The dry run confirms that the catalog maps to the expected Cloud project.
5. Push and review the catalog
After the source pull request merges:- every required plural category for the target locale;
- unchanged argument names such as
{count}; - glossary terms in each plural branch;
- descriptions and screenshots for ambiguous labels; and
- length in the real interface.
6. Pull and validate translations
Run:hl check catches missing target messages, placeholder mismatches, and icu_shape_mismatch errors.
Exercise plural branches in tests:
=0, one, and other. Add locale-specific cases when a language has more plural categories.
7. Pack catalogs for runtime
FormatJS catalogs contain review metadata. Pack target catalogs in place:defaultMessage and removes its description:
Record<string, string> expected by IntlProvider:
Troubleshooting
CI reports catalog drift
Runhl extract with the same paths and ignore patterns as CI, then commit lang/en-US.json.
icu_shape_mismatch appears
Compare argument names and ICU branches with the source. Fix the target in Cloud and approve the new revision. Do not suppress a real ICU mismatch.
React shows MISSING_TRANSLATION
Confirm the message ID exists in the pulled catalog, hl pack ran, and the app loads the target locale file passed to IntlProvider.

