Public canonical English UI copy and locale bundles for the Vouus platform.
| Surface | Domain | Product repo |
|---|---|---|
www |
www.vouus.com | web-public / marketing-web |
account |
account.vouus.com | core-platform / admin-web |
app |
app.vouus.com | core-platform / employee-web |
docs |
docs.vouus.com/legal/* | web-public / public-docs |
email |
(all send paths) | infra-email / email-templates |
Control Plane /cp/i18n (English UI) tracks coverage and links here. Operator CP chrome is not translated.
en (canonical), ja, ko, zh, ar, vi, th, id, ms, si, ur, hi, ru, my
Scoped rollout plan (account + app + www/home): docs/PLAN-translation-account-www-app.md — includes Phase F (ru/my) and Phase G (cross-domain locale cookie).
# 1. Extract EN from sibling product repos (erp-labs checkout)
npm run extract
# 2. Import existing employee-web translations (ko, ja, ar, vi, zh)
npm run batch:import-existing
# 3. Seed missing locales (cursor-ai first pass from EN)
npm run batch:seed-missing
# 4. Validate key parity + build keyword index
npm run verify
# 5. Push locale bundles back to product repos
npm run sync
# SEA locales (th, id, ms): generate + apply
npm run sea:generate && npm run sea:build
# New locales (ru, my): generate + apply
npm run locale:generate -- ru my && npm run locale:build -- ru my
# Mark human-reviewed locales
npm run mark:reviewed -- ar vi si ur hi- Open
sources/en/{surface}/{page}.page.json - Prompt (per target locale):
Translate values in this page JSON to {locale}. Keep all keys identical.
Preserve ICU placeholders like {n} and HTML tags. Do not translate: Vouus, Pregoi, Work App, Work Desk, AI Agent.
Output only the `keys` object as JSON for locales/{locale}/...
- Record
method: "cursor-ai"inversions/{pageId}.json
sources/en/— English only (edit here first)locales/{locale}/— translated page files (same paths as EN)manifest/pages.json— page registry (generated by extract)index/keywords.json— EN keyword index for CP searchversions/— per-page version history
Workflow .github/workflows/sync-product-repos.yml runs on pushes to main under locales/**, sources/en/**, or manifest/**, and opens PRs in the product repos.
Merge behavior (npm run sync / scripts/sync-to-apps.mjs):
- admin-web — deep-merges synced
accountnamespaces into existingdictionaries/{locale}.jsonso product-only keys/namespaces (not yet in web-i18n) are preserved. - marketing-web — deep-merges into existing
lib/i18n(preserves product-only EN keys), applies only non-EN-identical overlays from web-i18n, and never clobbers good product translations with English.
Required secret: PRODUCT_REPOS_TOKEN on this repository. The default GITHUB_TOKEN cannot read private sibling repos (core-platform, web-public, infra-email).
Create a fine-grained PAT (or classic PAT with repo scope) granted Contents: Read and write and Pull requests: Read and write on:
erp-labs/core-platformerp-labs/web-publicerp-labs/infra-email
Add it under Settings → Secrets and variables → Actions → New repository secret as PRODUCT_REPOS_TOKEN.
- PLAN-ko.md — Korean planning spec
- PLAN-en.md — English planning spec
- PLAN-translation-account-www-app.md — account / www home / app scoped translation (11 locales, docs excluded)
- PLAN-account-billing-demo-trial-i18n-ko.md — www Demo modal + trial QA + account Billing / Users detail / Integrations / Upgrade i18n
MIT — see LICENSE.