Skip to content

Structured locale leaves (non-English)

locales/en.json stays plain strings at every leaf — it is the source of truth for copy and key shape.

Each non-English file (locales/<lang>.json) uses structured leaves at the same dot paths:

json
{
  "value": "Translated text",
  "status": "translated",
  "confidence": 0.88,
  "needsReview": false,
  "source": "google-translate",
  "updatedAt": "2026-04-04T12:00:00.000Z"
}

Fields

FieldTypeMeaning
valuestringThe string passed to i18next at runtime (after stripping; see below).
status"pending" | "translated"pending — synced from English or not yet machine-translated; translated — filled or generated with a completed translation step.
confidencenumber | nullHeuristic 0–1 from generate/fill (null until scored).
needsReviewbooleanFlag for QA (e.g. low confidence or EN-identical output).
sourcestringHow value was produced (see below).
updatedAtstring (optional)ISO-8601 when the leaf was last written by tooling.

source values

ValueWhen
google-translateMachine translation from generate/fill.
copy-enVerbatim English (preserve-as-en keys, or English copy from sync for new paths).
sync-defaultReserved for future use when sync only patches metadata.
manualHand-edited (convention for future editor flows).
unknownLegacy string wrapped by sync before meta was added.

Runtime

src/i18n/index.ts loads locale JSON and passes bundles through stripLocaleBundleToStrings() so i18next only sees plain strings at leaves. Legacy files that still use bare strings are unchanged by the strip step.

Tooling

CommandRole
pnpm locales:syncAligns key shape to en.json, copies English into new paths as structured leaves, and merges missing meta keys on existing leaves.
pnpm locales:generate / pnpm locales:fillWrites value + meta after each translation API call.
pnpm locales:reviewRead-only aggregates over meta (no en.json comparison).
pnpm locales:validate:qualityParity vs en.json and English-identical detection (uses string values from leaves).

Shared types and helpers live in apps/web/scripts/locales/shared/localeLeaf.ts.