Overrides
Overrides let a message serve different translations to different audiences at runtime, based on context, segments, attributes, and optional feature or experiment integrations.
Basic structure#
An override lives inside a message's overrides array. Each override has:
key: a unique stable identifier within the message- one of
segmentsorconditions(or both) translations: the alternate locale-to-string map
translations: en: Install the app nl: Installeer de appoverrides: - key: platform-ios segments: platform-ios translations: en: Download on the App Store nl: Download in de App Store - key: platform-android segments: platform-android translations: en: Get it on Google Play nl: Download via Google PlayOverride keys#
Every override must have a unique key within the message. The key:
- is used for merging during sets-based promotion
- appears in CSV export rows with the format
messageKey:overrideKey - is required before a message can participate in
promote
overrides: - key: plan-pro # stable identifier segments: plan-pro translations: en: Your Pro workspace is readySegment-based overrides#
Reference a named segment when the condition is reusable across multiple messages.
overrides: - key: mobile segments: platform-mobile translations: en: Download the appUse logical groups with and, or, or not to compose multiple segments:
overrides: - key: dutch-web segments: and: - dutch-account - platform-web translations: en: Your Dutch workspace is ready nl: Je Nederlandse werkruimte staat klaarThe wildcard * matches all users:
overrides: - key: universal segments: "*" translations: en: Special message for everyoneCondition-based overrides#
Use conditions directly on an override when the logic is specific to one message and not worth extracting into a named segment.
Single inline condition:
overrides: - key: pro-user conditions: attribute: plan operator: equals value: pro translations: en: Your Pro plan is activeCompound condition with and:
overrides: - key: adult-mobile conditions: and: - attribute: age operator: greaterThanOrEquals value: 18 - attribute: platform operator: equals value: mobile translations: en: Adult mobile contentFeature and experiment conditions#
Attribute conditions and segments work with Messagevisor context directly. Overrides can also reference feature flags and experiment variations when your SDK or module setup provides resolvers, for example from a Featurevisor integration:
overrides: - key: faster-checkout conditions: and: - feature: new-checkout operator: isEnabled - experiment: checkout-copy operator: hasVariation value: bold translations: en: Try the faster checkout - key: classic-checkout conditions: feature: new-checkout operator: isDisabled translations: en: Your classic checkout is readyAvailable feature/experiment operators:
isEnabled/isDisabled: based on a feature flaghasVariation: based on the active experiment variation
Without resolvers, prefer modeling audience data as Attributes in the Messagevisor context.
Condition operators reference#
Attribute conditions support these operators:
| Operator | Value type | Notes |
|---|---|---|
equals | any | |
notEquals | any | |
exists | none | attribute is present in context |
notExists | none | attribute is absent from context |
greaterThan | number | |
greaterThanOrEquals | number | |
lessThan | number | |
lessThanOrEquals | number | |
contains | string | substring match |
notContains | string | |
startsWith | string | |
endsWith | string | |
before | date string | date comparison |
after | date string | date comparison |
includes | string | value is in an array attribute |
notIncludes | string | |
in | array of values | attribute is in the list |
notIn | array of values |
Override evaluation order#
Messagevisor evaluates overrides top-to-bottom and returns the first matching override.
That means:
- order matters
- more specific overrides should appear before more general ones
- changing order can change runtime behavior
Override translations and locale inheritance#
Each override has its own translations map, and locale inheritance applies to override translations too.
If en-US inherits from en via inheritTranslationsFrom: en, the override translation for en will be inherited by en-US unless en-US has an explicit override translation.
Description and summary on overrides#
Overrides also accept description and summary fields for documentation purposes:
overrides: - key: mobile description: Shorter copy shown on narrow mobile screens summary: Mobile variant segments: platform-mobile translations: en: Contact usThese appear in CSV exports and in the catalog.
Overrides and build#
During build, the builder:
- reads all overrides for each message
- evaluates target context against conditions and segments
- keeps only the overrides that remain reachable for the target's known context
- includes only the segments and attributes used by surviving overrides
This means the runtime datafile can have fewer overrides than the authored source. That is intentional: target context eliminates impossible branches ahead of runtime.
Overrides in CSV export#
When exporting to CSV, each override appears as a separate row. The message key column uses the format:
messageKey:overrideKeyFor example, auth.installApp:platform-ios would appear as a row with its own translation columns.
The separator is configurable via exportOverrideKeySeparator in Configuration.
Overrides and promotions#
During promote, override arrays are merged by key. This means:
- overrides from the source set are matched with overrides of the same key in the destination set
- new override keys from the source are added to the destination
- override keys that only exist in the destination are preserved
This merging behavior requires that all overrides have unique keys before promotion.
promotable on overrides#
Setting promotable: false on an override prevents it from being updated during promotion even if the message itself is promotable:
overrides: - key: environment-specific promotable: false segments: platform-web translations: en: Environment-specific textEdge cases and behavior notes#
Conditions vs segments#
Use a named segment when the condition applies to more than one message. Use inline conditions when the logic is specific to one message and adding a segment file would just add noise.
Wildcard segments#
segments: "*" matches all users. This is useful when you want an override that always fires regardless of context, such as a temporary banner or one-time announcement.
The * wildcard for conditions#
You can also set conditions: "*" on an override. This behaves the same as segments: "*" - the override fires for all users.

