Appearance
UI Localization Guide
Use this guide when adding or changing text that people see in an RIGOR Web application. It explains which translations are shared, which remain owned by a module, how a browser chooses a language, and how to validate locale parity.
ASCEND, Composer, PACE, LabBridge, LabFlow, and PRISM share one language-preference contract while keeping separate product dictionaries. English is the fallback language; Simplified Chinese and Spanish are the other supported locales.
Structure
text
packages/ui-i18n/src/common.js shared actions, chat, and state labels
packages/ui-i18n/src/index.js detection, persistence, and i18next setup
*/web/admin/*/locales.js English and Chinese product copy
*/web/admin/*/locales.es.js Spanish product copy where split out
labflow/web/admin/src/locale.js native DOM localization adapter
prism/web/admin/src/locales.js PRISM product copy
scripts/check-ui-locales.mjs locale key parity checkKeep product-specific text in the owning application. Move a key to common.js only when its meaning and wording are genuinely shared.
The React applications use i18next directly. LabFlow keeps its existing native JavaScript architecture and applies the same dictionaries and preference contract through locale.js; this avoids coupling localization to a framework migration.
Language preference
The browser resolves a language in this order:
?lang=en,?lang=zh-CN, or?lang=essdlx_localecookiesdlx.localelocal storage value- browser language
- English
On *.sdl.digauto.org, the cookie is written with Domain=.sdl.digauto.org, Path=/, SameSite=Lax, and Secure, so the selection follows the user between RIGOR modules. Local development uses a host-only cookie and local storage.
The locale cookie is a UI preference, not an authentication or authorization mechanism.
Every module exposes the same segmented English, Simplified Chinese, and Spanish control. Do not replace it with a select menu: all supported choices should remain visible and the active language should be immediately apparent.
Translation boundary
Translate navigation, commands, labels, known status enums, validation headings, empty states, and help text. Do not translate experiment goals, agent messages, device identifiers, parameter keys or values, artifact content, backend errors, or durable audit records.
Unknown backend enum values fall back to a readable version of the original value. Add an explicit translation when the enum becomes part of a stable contract.
Adding copy
Add the same nested key to en, zh-CN, and es in the owning locale resources, then render it with tr("section.key"), tx("Visible label"), or useTranslation() inside reusable React components. LabFlow's native adapter translates exact known UI strings and attributes; keep YAML, identifiers, device data, and runtime output outside that boundary. Use interpolation for counts and dynamic labels rather than concatenating translated fragments.
Run the parity check directly:
bash
node scripts/check-ui-locales.mjsAll six application builds run their relevant locale check as part of npm run build.