Building blocks
Targets
Targets are how Messagevisor creates smaller, purpose-built datafiles for specific applications, platforms, or surfaces. They sit between authored definitions and runtime output.
What a target controls#
A target can control:
- which messages are included
- which messages are explicitly excluded
- which locales are emitted
- partially-known
context, for removing impossible override branches ahead of runtime - locale-specific
formatsoverrides - which resolved format presets are included or excluded
- whether generated datafiles should keep only actively used named ICU formats
- datafile serialization options
- target-level examples and tests through surrounding workflows
Example#
description: Web datafile# everything below is optional# include only these messages following the patternincludeMessages: - auth* - nav*# exclude these messagesexcludeMessages: nav.legacy*# emit datafiles for these locales onlylocales: - en - en-US# apply this partially known context beforehandcontext: platform: web# include only selected resolved format presetsincludeFormats: number: "*" date: short* time: - short - long*# exclude matching resolved format presetsexcludeFormats: number: moneyCode# alternatively, auto-include only named ICU number/date/time presets# used by emitted messages and overrides# includeOnlyUsedFormats: true# generated datafiles should be pretty printedpretty: trueWhy targets matter#
Targets let you avoid shipping one giant universal translation bundle when your applications only need slices of the project.
That gives you:
- smaller datafiles
- fewer messages and overrides at runtime
- fewer segments and attributes in the output
- more predictable platform-specific behavior
Description#
Human readable description of the target for documentation purposes:
description: Web application datafileInclude messages#
includeMessages determines which messages are included in the target. Use a string for one pattern, or an array for multiple patterns.
- If
includeMessagesis omitted, all messages are included by default (before any exclusions are applied). - If
includeMessages: []is present, no messages are included. - Supports
*wildcards for flexible pattern matching.
Typical includeMessages patterns:
auth*- all messages under theauthnamespacenav.*- all messages nested undernavbilling.checkout*- all checkout messages
Example:
includeMessages: - auth* - nav*When the target should include everything, prefer the scalar form:
includeMessages: "*"Exclude messages#
excludeMessages removes messages that match these patterns from the set selected by includeMessages. Like includeMessages, it accepts either one string pattern or an array of patterns, and supports * wildcards.
Example:
includeMessages: "*"excludeMessages: - admin* - internal*In this example, all messages are included except those starting with admin or internal.
Resolution order:
- Start from all messages in the project.
- Include anything that matches
includeMessages; ifincludeMessagesis omitted, treat it as["*"]. - Drop anything that matches
excludeMessages.
Locales#
The locales list controls which locale datafiles get emitted for the target. A locale must exist in locales/<key>.yml to be referenced here.
Locale inheritance still applies at build time: en-US can inherit from en for translations and formats. The target's locale list says which datafiles are produced, and inheritance says how their content is resolved.
locales: - en - en-USIf omitted, all locales are emitted.
Context#
context on a target represents values that are already known for that target at build time.
For example:
context: platform: webThis matters because:
- build can simplify or remove impossible override branches ahead of runtime
- evaluate/examples/tests that use a target inherit this target-known context behavior through the built datafile path
Think of target context as "always true for this output artifact", not "an optional runtime hint."
Formats#
Targets can override locale format presets per locale. The formats field is keyed by locale and follows the same structure as locale-level formats.
Target formats can pin values such as currency or timeZone, or leave them out so the SDK fills them from instance state at runtime. When a target declares the same format style as the resolved locale, the target style object replaces that locale style in full. Other styles still come from locale inheritance.
formats: en-US: number: money: style: currency currency: USD currencyDisplay: narrowSymbol en-GB: number: money: style: currency currency: GBP currencyDisplay: narrowSymbol de-DE: number: money: style: currency currency: EUR currencyDisplay: symbolRuntime format precedence is:
- SDK constructor
defaultFormatsfor the active locale, as runtime defaults - locale inheritance chain (e.g.
en-USinheriting fromen) - locale's own
formats - target
formatsfor the selected locale - per-call runtime overrides passed at evaluation time
This is one of the most important precedence chains to understand when a formatted value looks wrong. A target override takes precedence over what the locale file defines.
Include formats#
includeFormats filters which resolved format presets are included in generated datafiles for this target.
The field is grouped by format type. Each type accepts one string pattern or an array of patterns. Patterns match the style or preset name inside that type:
includeFormats: number: "*" date: short* time: - short - long*If includeFormats is omitted, all resolved formats are included before exclusions are applied. If includeFormats is present, only matching format types and style names are included.
Exclude formats#
excludeFormats removes matching format presets from the set selected by includeFormats.
includeFormats: number: - decimal* - money* date: short*excludeFormats: number: moneyCodeFormat filtering happens after locale inheritance and target formats overrides are resolved. In other words, target overrides can still change a format style first, and includeFormats / excludeFormats then decide whether that resolved style ships in the datafile.
Include only used formats#
includeOnlyUsedFormats is a datafile-size optimization. When set to true, Messagevisor keeps only named ICU format presets that are actively referenced by the messages and overrides emitted into that target datafile.
includeOnlyUsedFormats: trueThis currently detects named ICU number, date, and time styles, such as:
{amount, number, money}{startsAt, time, short}{createdAt, date, compact}Use includeOnlyUsedFormats when the target should automatically follow message usage. Use includeFormats / excludeFormats when you want explicit pattern-based control. includeOnlyUsedFormats: true cannot be combined with includeFormats or excludeFormats.
Pretty#
Controls whether generated datafiles are written in a human-readable, formatted style.
pretty: true- Default:
false - Behavior: If
true, the target's generated JSON datafiles are written with indentation for better readability. Iffalse, datafiles are written compactly without extra whitespace.
Stringify#
Determines how complex conditions and segments are serialized inside the datafile.
stringify: falsestringify: true- Default:
true - Behavior: If
true, complex generatedconditionsandsegmentsare emitted as JSON strings, making the datafile more compact and fast to parse. Iffalse, they are included as structured objects, which is useful for debugging and inspection.
Revision from hash#
Controls how the revision field is generated for the target’s datafile.
revisionFromHash: true- Default:
false - Behavior: If
true, uses a hash of the target's datafile content as the datafilerevision. This ensures that any change in content results in a new revision hash, making updates easy to track. Iffalse, revision may be set using another strategy.
These options are configured at the target level, letting you choose, for each target, whether you want compact files ready for a CDN or more inspectable output. For example, a production target may use stringify: true and pretty: false for performance, while a debug target uses stringify: false and pretty: true.
Build output#
build writes one datafile per target and locale combination:
datafiles/messagevisor-web-en-US.jsonThat datafile includes:
- target-filtered translations
- only needed segments and attributes
- resolved target-aware formats
- target metadata such as the target key
See Building datafiles for the full output model.
Nested target files#
Most projects can keep target files flat, such as targets/web.yml and targets/mobile.yml. For larger projects, target files may also be organized in subdirectories.
targets/apps/admin.ymlThis target's key is apps.admin. When built for en-US, Messagevisor keeps the key in the datafile but mirrors the target directory structure in the output path:
datafiles/apps/messagevisor-admin-en-US.jsonThe same key is used anywhere you reference the target:
$ npx messagevisor build --target=apps.admin --locale=en-USEvaluation#
Targets affect:
buildexamplesevaluate --messageevaluate --rawMessagebenchmark- target tests
- catalog export and UI
This means target behavior is not just about file naming. It changes the actual runtime shape and can change which overrides or formats are visible.
Tests#
Target tests validate message inclusion, format presets, and evaluated translations against target behavior:
target: webassertions: - description: Auth messages are included expectedToIncludeMessages: - auth.signin - auth.signout - description: Admin messages are not included expectedToNotIncludeMessages: - admin.dashboard - description: Money format for en-US locale: en-US expectedFormats: number: money: currency: USD - description: Welcome message evaluates correctly locale: en-US message: dashboard.welcome values: name: Ada expectedTranslation: Welcome, Ada!Assertions can test structure (expectedToIncludeMessages, expectedFormats) and runtime behavior (expectedTranslation) in the same spec file.
See Testing for the full assertion shape.
Edge cases and behavior notes#
Message inclusion and runtime evaluation are related, but not identical#
If you evaluate a known message key against a built target datafile and that target excludes the message, the behavior follows the real SDK path. Messagevisor does not invent a separate "target test failure" runtime for that case.
Target context is different from runtime context#
- target context shapes the built artifact
- runtime context is supplied at evaluation time
You can think of target context as a compile-time assumption and runtime context as a per-call input.
Targets are not deployment environments#
Some teams map them that way, but a target is better understood as a runtime artifact shape. Sets model parallel authoring trees; targets model output slices.

