Internal concepts
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 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 keeps that override local to its current set even if the message itself is promotable:
overrides: - key: environment-specific promotable: false segments: platform-web translations: en: Environment-specific textDuring promotion, a non-promotable source override is not copied into the destination and does not update an existing destination override with the same key. If the destination override itself has promotable: false, it is also protected from source updates.
Skipped overrides do not pull in their referenced segments or translation locales used only by those overrides. Attribute definitions are authoring schemas and never appear in runtime datafiles. Surviving conditions can still reference context field names; applications supply their values at runtime.
Edge 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.