mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-15 22:21:20 +00:00
3.0 KiB
3.0 KiB
Dashboard i18n Guide
Last Updated: 2026-03-02
This document describes the internationalization (i18n) architecture used by the CCS Dashboard (ui/), how locale selection works, and how to add new languages safely.
Scope
Dashboard i18n currently covers UI text rendered by React components.
- Supported locales today:
en(English)zh-CN(Simplified Chinese)vi(Vietnamese)
- Locale state is persisted in browser localStorage using
ccs-ui-locale. - Fallback language is
en.
Out of scope:
- CLI terminal output localization
- Backend/API payload localization
Architecture
Initialization
- File:
ui/src/App.tsx import '@/lib/i18n'initializes i18next once before routes render.
Translation resources
- File:
ui/src/lib/i18n.ts - Contains
resourcesobject with locale blocks:en.translationzh-CN.translationvi.translation
- Uses
initReactI18nextfor React integration.
Locale utilities
- File:
ui/src/lib/locales.ts - Core helpers:
normalizeLocale(locale)maps browser/storage values to supported app locales.getInitialLocalechooses stored locale, then browser locale, thenen.persistLocalewrites normalized locale to localStorage.
Language switcher
- File:
ui/src/components/layout/language-switcher.tsx - Uses
react-i18next+ shadcnSelect. - Calls
persistLocaleandi18n.changeLanguageon selection.
Key Conventions
Translation key naming
Use dot-notation namespaces by feature area:
nav.homecursorPage.titlesettingsTabs.web
Keep key names stable and semantic to minimize churn across locales.
Pluralization
For count-based strings, use i18next suffix rules:
<key>_one<key>_other
Examples exist in sync/account counters.
Interpolation and rich text
- Use interpolation for runtime values:
t('key', { value }). - Prefer plain text keys whenever possible.
- If formatting is required (for example bold segments), use
<Trans />instead ofdangerouslySetInnerHTML.
Adding a New Locale
When adding a locale such as Thai (th):
- Add locale id to the supported locale list in
ui/src/lib/locales.ts. - Add locale display label under
translation.localeinui/src/lib/i18n.ts. - Add a full
<locale>.translationblock with all keys. - Verify fallback behavior remains
enfor missing keys. - Run UI validation and i18n tests:
cd ui && bun run validatecd ui && bun run test:run tests/unit/ui/i18n/language-switcher.test.tsx
- Add or update key-parity tests to catch locale drift.
Current issue driving the Vietnamese rollout:
Contributor Checklist
Before opening a PR that touches i18n:
- New UI strings are translated in all supported locales.
- No raw key literals appear in UI at runtime.
- No unsafe HTML injection path introduced for translated content.
uivalidate/test commands pass.- This document is updated if architecture or conventions changed.