en is the source locale you translate from, and
any locale left untranslated falls back to it.
Your app has two kinds of translatable text, and both flow through the same
locales/ catalog:
- Manifest labels — object and field names, view titles, menu items, and other strings declared in your app’s metadata.
- Front-component strings — the UI text your React front components render.
Marking front-component strings
Import the translation helpers fromtwenty-sdk/front-component:
When to use which
<Trans>…</Trans>— static text in JSX. Use themessageandvaluesprops for interpolation (<Trans message="Hi {name}" values={{ name }} />); interpolating directly in the children is not statically extractable.useTranslate().t— dynamic strings inside a component. Re-renders when the user switches language. Prefer this inside render.t(...)(imported directly) — eager translation usable anywhere, including event handlers, helpers, and module scope — not only inside render.msg(...)— a lazy descriptor for strings declared as data (constants, config). Resolve it later witht(descriptor).
Context
Passcontext to disambiguate identical source strings that translate
differently:
Extracting and translating
Run the extract command from your app directory:t()/msg()/<Trans>
strings from your front-component source into locales/<locale>.json, keyed by
source string. Fill in the translations:
{name} are substituted at runtime — keep them in the
translation. Any string left empty falls back to the source text.
How it runs
twenty dev:build compiles the catalogs and serves the right language for the
current user: manifest labels are resolved server-side, and front-component
catalogs are baked into each component bundle. At runtime a component reads the
locale from its execution context (the host’s current language) and resolves
each string against its catalog, falling back to the source when a translation
is missing. Switching language in the host re-renders <Trans> and
useTranslate().t strings live.
Because catalogs are compiled at build time, updating a translation means
re-running twenty dev:build (and redeploying), the same as any other change.
Translations are compiled by
twenty dev:build (and twenty apply). The
continuous twenty dev watch shows source strings, so test localized output
with a one-off build.<Trans> text children may span multiple lines — whitespace is collapsed the
same way JSX collapses it, so <Trans>Welcome\n back</Trans> and the extracted
key both become Welcome back.