Inheritance
Inheritance lets a locale reuse translations, formats, and examples from another locale while only authoring the differences. It is the workflow you want for regional variants such as en-US, en-GB, nl-NL, and nl-BE.
What can be inherited#
Locale files support three inheritance fields:
| Field | Purpose |
|---|---|
inheritTranslationsFrom | Reuse message and override translations from another locale |
inheritFormatsFrom | Deep-merge format presets from another locale |
mergeExamplesFrom | Include examples from another locale in CLI examples output and generated catalog views |
These fields are independent. A locale can inherit translations from one parent, formats from another parent, or use the same parent for both.
Author the base locale#
Start with the broadest reusable locale:
description: English baseformats: number: money: style: currency currency: USD currencyDisplay: symbol date: long: year: numeric month: long day: numericdescription: Sign in button labeltranslations: en: Sign inThis base locale becomes the source of truth for all regional variants unless they need a different string or format.
Add regional locales#
Regional locales can inherit both translations and formats:
description: English (United States)direction: ltrinheritTranslationsFrom: eninheritFormatsFrom: enmergeExamplesFrom: enOverride only the parts that differ:
description: English (United Kingdom)direction: ltrinheritTranslationsFrom: eninheritFormatsFrom: enformats: number: money: style: currency currency: GBP currencyDisplay: symboltranslations: en: Billing address en-GB: Billing address en-US: Billing addressWhen a regional translation matches the inherited value, it is redundant and can be pruned later.
Translation resolution#
Given this chain:
en-GB -> enMessagevisor resolves each message for en-GB in this order:
- direct
en-GBtranslation - inherited
entranslation - if still missing, that message key is omitted from the datafile for this locale; at runtime the SDK applies missing-key behavior if the app requests it
Override translations follow the same rule. If an override has en copy and the en-GB locale inherits from en, the override is available in the en-GB datafile unless en-GB overrides it directly.
Format resolution#
Runtime format resolution is a deep merge:
- SDK constructor
defaultFormatsfor the active locale, as runtime defaults - inherited parent formats
- child locale formats
- target-level format overrides for that locale
- SDK per-call format overrides
Deep merge means en-GB can replace only formats.number.money.currency while keeping the rest of the parent format preset families.
Build impact#
Inheritance is resolved when building datafiles:
$ npx messagevisor build --target=web --locale=en-GBThe resulting datafile contains the resolved translation and format behavior needed by the SDK. The application does not need to know which locale authored the original value.
Testing inheritance#
Use locale tests for resolved formats:
locale: en-GBassertions: - description: Inherits date format and overrides money currency expectedFormats: number: money: currency: GBP date: long: month: longUse message tests for inherited translations:
message: auth.signinassertions: - description: en-GB inherits base English copy locale: en-GB target: web expectedTranslation: Sign inExporting inherited work#
CSV export records whether each locale cell is direct, inherited, or missing when status columns are enabled:
$ npx messagevisor export --locale=en-GB --target=webUseful filters:
$ npx messagevisor export --locale=en-GB --onlyUntranslated$ npx messagevisor export --locale=en-GB --onlyDirectlyUntranslatedUse --onlyUntranslated when inherited values count as translated. Use --onlyDirectlyUntranslated when a translator should provide direct regional copy even if a parent locale currently fills the gap.
Importing regional translations#
After a translator returns a CSV, preview the import:
$ npx messagevisor import exports/en-GB.csvThen apply it:
$ npx messagevisor import exports/en-GB.csv --applyApplied imports update only changed direct translations. If a CSV value matches the inherited result and there is no direct value, Messagevisor can skip it instead of creating redundant regional copy.
Pruning redundant translations#
Over time, regional locale files can accumulate direct translations that match inherited parent values. Preview redundant translations:
$ npx messagevisor prune --translations --locale=en-GBApply the cleanup:
$ npx messagevisor prune --translations --locale=en-GB --applyYou can narrow pruning by target or message patterns:
$ npx messagevisor prune --translations --target=web --includeMessages="checkout*"Pruning redundant formats#
Format pruning removes child locale format entries that duplicate inherited effective formats:
$ npx messagevisor prune --formats --locale=en-GB$ npx messagevisor prune --formats --locale=en-GB --applyThis keeps locale files readable. The child locale should only show what truly differs from the parent.
Finding duplicate translation values#
Use find-duplicates when you want to audit repeated resolved copy across message keys:
$ npx messagevisor find-duplicates$ npx messagevisor find-duplicates --locale=en-GBThe command applies inheritTranslationsFrom before comparing values, so duplicates introduced through fallback chains are visible. It ignores overrides, archived messages, and empty values. The catalog exposes the same data in each locale's Duplicates tab.
Sets-aware inheritance#
In sets-based projects, each set has its own locale files and inheritance chains. Use --set to inspect or clean one environment:
$ npx messagevisor test --set=staging --keyPattern=en-GB$ npx messagevisor prune --translations --set=staging --locale=en-GBPromotion copies authored definitions between sets. It does not magically merge inheritance chains across sets, so validate the destination after promotion.
Review in the catalog#
The catalog helps reviewers see whether a regional locale relies on inherited copy or direct copy. Pair catalog review with examples so product and localization reviewers can inspect resolved output without reading every locale file. The same authored examples can also be inspected in the terminal with npx messagevisor examples.

