Skip to content

Contributing a translation

ReduceWaste ships content in many locales, read from one locale list (i18n/locales.json) that is the single source of truth for which locales exist and which are right-to-left. Three kinds of content are translated, each in its own place:

  • App UI strings — app/messages/<locale>/*.json. Every UI string is required to live here first; a hard-coded string in a component fails lint, so there is always a key to translate.
  • Docs content — docs/src/content/docs/<locale>/**, one tree per locale, mirroring the English tree this page lives in.
  • Recipe and glossary content — recipes/_i18n/<locale>/** and knowledge/glossary/<locale>.yaml. A recipe’s own i18n_keys list names exactly which of its fields need translating (mounting, wiring, safety notes, validation check); the rest of a recipe — ids, numeric ranges, the detector binding — stays the same in every locale.
Terminal window
uv run rw i18n check
npm -w app exec vitest run tests/i18n

The first checks that every locale has a translation for every required key with no unexpected extras; the second runs the app’s own i18n test suite. Both are expected to pass with zero problems before a translation change is proposed.

Machine identifiers, signal ids, numeric ranges and units, and any example part numbers stay identical across every locale — only the human-facing explanation text changes.

Translations of safety_notes and validation.check get the same scrutiny as a new recipe’s English text: a mistranslated lockout/tagout instruction is a safety problem, not a typo, so these fields are reviewed for accuracy against the source English, not just fluency.