Translations

The Ingot has no language files of its own. Every visible string is a property the caller passes in already translated.

The rule

No Ingot primitive translates a single word. The kit has no language files and never touches the translation context. Everything the user will see or hear arrives as a property — already in the right language.

That is deliberate, not a gap. A primitive that translates its own labels has to bring its own namespace along — and that namespace then fights the screen’s namespace over who owns the word “Cancel”. This kit does not have that argument, because it never owns the word.

What that means in practice

Do not forget the labels nobody sees

The most common mistake is not untranslated buttons — everyone spots those. It is the strings only a screen reader sees, which therefore stay in the original language even in an otherwise-translated admin, and nobody reports them:

  • closeLabel — the dialog’s close icon. Without it a screen reader announces just “button”.
  • caption on a table — a description that is never painted on screen.
  • actionsLabel — the header of the row-actions column.
  • loadingLabel — the “loading” announcement. Optional in the type, but once loading can happen the announcement is empty without it.

A few labels the kit says itself — “Undo” on a toast, the hint’s bulb and close button, “set” on a secret field. Those come from the IngotProvider dictionary: English without a provider, Czech with lang="cs", and overridable one by one through labels. A component’s own prop always wins.

Dictionary: Simple / Expert

Technical terms come in two forms: a plain description for a reader still learning the domain, and the expert term for the one who lives in it. Which form appears is the user’s choice — the modes are Simple, Expert and the default Both.

The “Both” mode shows the expert term with the plain description in parentheses after it — not in a tooltip. Tooltips do not work on touch screens, screen readers skip them without extra wiring, and in-page search cannot find text that is not in the page. The parenthesis is longer, but everyone sees it.

Try it: flip the Dictionary control below this paragraph and watch the terms in the table re-render. The control sits with the demo because it drives no other table on this site — the documentation writes about the interface, not about manufacturing. In the application it is an account setting and applies wherever a domain term appears.

Dictionary
Dictionary terms in the current mode
KeyWhat the user sees
nestingNesting (Part layout on the sheet)
setup_timeSetup time (Machine preparation)
tolerance_classTolerance class (Manufacturing precision)

How to add a term

Terms live in one registry next to the doc web’s other language helpers. Each term is a pair of variants, both already translated into every language the doc web carries.

  1. Add the key to the term registry: expert is required, simple only when the term has a real plain description — not just a synonym.
  2. The registry’s type enforces every language: a variant missing a translation fails the type check. A language cannot be promised without being written.
  3. In content, select via termLabel(key, mode, language) — never hard-code one of the variants. That would disconnect the text from the user’s choice.
  4. A term without a simple variant shows its expert form in every mode — a missing description never ends up as empty text.

How a demo is written

The demo is the part of the page a reader looks at first. A page that translates everything except the demo looks finished and is not — which is worse than translating nothing, because nobody notices.

So a demo takes the reader's language and keeps every text it says in one constant at the top of the module. At the top on purpose: the code listing under the demo is that same file, so the reader sees where the texts come from as well.

const TEXT: Localized<Record<string, string>> = {
  cs: { save: "Uložit změny" },
  en: { save: "Save changes" },
};

export function Demo({ lang }: { lang: DocLang }): JSX.Element {
  const t = TEXT[lang];
  return <Button>{t.save}</Button>;
}

Text written in one language anywhere else in a demo is a mistake the repository's checks catch — not the reader in the other language.

Where to find the specific labels

Every component page has its own Translations section listing exactly the labels that component asks for. This page holds the rule; the list is over there.