Channels · Writing for translation
Channels

Writing for translation

Four locales, one glossary. Translation is not synonym swapping — it is the same product concept in natural local language.

Locales

LocaleRole
en-GBCanonical source for new product strings
en-USSpelling and minor idiom variants
pt-PTEuropean Portuguese — formal B2B register
pt-BRBrazilian Portuguese — distinct sports and UI conventions

Workflow

  1. Write or update en-GB string using glossary
  2. Translate with glossary terms locked — native-translator workflow for natural phrasing
  3. Human review for legal, trust, and pricing strings
  4. Run npm run i18n:check --prefix frontend for key parity

i18n key conventions

Mirror product structure — example pattern:

business.organizerDashboard.event.tabs.collect

  • Namespace per app area (common, business)
  • No English prose in keys
  • New spec files must be registered in frontend package.json test script

ICU and plurals

Use ICU message format for counts:

{count, plural, one {# participant} other {# participants}}

Engineering contract

The ui package ships no user-facing strings. Every label, placeholder, and empty state is passed from the app. Portuguese defaults in primitives were removed — all call sites must supply locale-aware strings.

pt-PT vs pt-BR

  • Do not ship one Portuguese string for both locales
  • tu/você choices follow established frontend conventions per locale file
  • Sports terms differ (e.g. race naming) — consult native reviewers
Sporting Scouter Content Style Guide
Component-enforceable rules: design-system.sportingscouter.com/voice. Tokens from packages/config/tailwind/theme.css.