Internationalization (ICU MessageFormat)
Category: Quality Attributes · Areas: ui, frontend
Description
Category
internationalization
Areas
ui, frontend
Components
- Message format: ICU MessageFormat
- String management: Externalized string catalogs (no hardcoded strings)
- Direction: Bidirectional text support (LTR and RTL)
Constraints
- All user-facing strings must go through the i18n system
- No string concatenation for user-facing messages (use ICU plurals, select)
- Date, time, number, and currency formatting must be locale-aware
- Default locale must be explicitly declared
When to use
Any project that serves users in multiple languages or locales, or any project that may need localization in the future. Starting with i18n is far cheaper than retrofitting.
Artifact Impact
Selecting this concern requires these artifacts to change (a selected concern absent from them is drift):
- TD: ICU MessageFormat, externalized string catalogs, locale-aware formatting, declared default locale
- DESIGN_SYSTEM: bidirectional (LTR/RTL) text support
Practices by activity
Agents working in any of these activities inherit the practices below through runtime work context, such as a DDx bead context digest.
Requirements (Frame activity)
- All user stories involving user-facing text must specify i18n handling
- Target locales must be declared in the project config
- Default locale must be explicitly set
Design
- All user-facing strings externalized to message catalogs
- Use ICU MessageFormat for plurals, gender, select, and interpolation
- No string concatenation for UI messages — use format patterns
- Design layouts for text expansion (translations are often 30-50% longer)
- RTL layout support from the start if any target locale requires it
Implementation
- String catalog files per locale (e.g.,
messages/en.json,messages/ja.json) - Use the platform’s i18n library (react-intl, next-intl, gettext, etc.)
- Date/time: use
Intl.DateTimeFormator equivalent — never manual formatting - Numbers/currency: use
Intl.NumberFormator equivalent - No hardcoded strings in components — all text comes from catalogs
- ICU message keys should be descriptive:
user.greetingnotmsg_001
Testing
- Pseudo-localization testing to catch hardcoded strings and layout issues
- Verify all user-visible text renders correctly in longest target locale
- Test RTL layout if applicable
- Verify date/number formatting respects locale settings
Innsigle seal: model-primary by HELIX
The signature covers the markdown source of this page, not these HTML bytes. This page quotes that seal; verify it against the source file.
- Composition
- model-primary
- Issuer
- HELIX
helix - Signing key
ed25519:b0865d76d834a52c48506414d16f4e5a(build key)- Signed source
concerns/i18n-icu.md- Signed
- 2026-09-23T14:11:58Z
- Content digest
sha256:0bfe023d…c936f9bb
This build key is endorsed by the human key for build signing; the signature is not a detector and not a truth guarantee.
Raw attestation JSON
{
"payload": {
"innsigle": "1",
"type": "https://innsigle.dev/claim/colophon/v1",
"issued_at": "2026-09-23T14:11:58Z",
"issuer": {
"id": "helix",
"name": "HELIX",
"key_id": "ed25519:b0865d76d834a52c48506414d16f4e5a",
"key_url": "https://documentdrivendx.github.io/helix/.well-known/innsigle/keys.json"
},
"subjects": [
{
"uri": "https://documentdrivendx.github.io/helix/concerns/i18n-icu/",
"digest": {
"alg": "sha256",
"value": "0bfe023d13c6980088233ecba39634cb99d73aa2f27d67d5a6973469c936f9bb"
}
}
],
"colophon": {
"schema_version": "1",
"composition": "model-primary",
"ingredients": [
{
"kind": "model",
"name": "Claude",
"role": "draft"
},
{
"kind": "tool",
"name": "sloptimizer",
"role": "rewrite"
},
{
"kind": "human",
"name": "operator",
"role": "structure-edit"
}
],
"notes": null
}
},
"payload_encoding": "json",
"signatures": [
{
"key_id": "ed25519:b0865d76d834a52c48506414d16f4e5a",
"alg": "ed25519",
"sig": "jWfrgoVw-cvusO93SwO0hgNfKcPmQtsutRLrRwUmuhMQBlq21BLZ1UfA6ap0lT5nHlriN5B3fmwHGUfSoi5XCg",
"signed_at": "2026-09-23T14:11:58Z"
}
]
}