i18n
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
---
|
||||
name: add-language
|
||||
description: Add or remove a UI language/locale — config, catalog generation, translation agents, SMS/date/meta integration, and verification. Use when asked to add, enable, support, or remove a language.
|
||||
---
|
||||
|
||||
# Adding a language
|
||||
|
||||
Example: adding French (`fr`). Five places name the locale set — update all:
|
||||
|
||||
1. `src/lib/i18n/index.ts` — `SUPPORTED_LOCALES` + `LOCALE_LABELS` (label in
|
||||
the language itself, no region clarifier: `fr: "Français"`).
|
||||
2. `lingui.config.ts` — `locales`.
|
||||
3. `src/lib/mantine/mantine-provider.tsx` — `DAYJS_LOCALE` map + the matching
|
||||
`import 'dayjs/locale/fr'` (calendar month/weekday names come from dayjs;
|
||||
without this, calendars stay English).
|
||||
4. `src/lib/i18n/meta.ts` — `OG_LOCALE_BY_LOCALE` (fr → fr_FR).
|
||||
5. `src/lib/twilio/index.ts` — `TWILIO_VERIFY_LOCALES` ONLY if Twilio Verify
|
||||
supports the code (https://www.twilio.com/docs/verify/supported-languages).
|
||||
Unsupported codes must stay out — the allowlist silently falls back to the
|
||||
service-default English SMS instead of failing the login send.
|
||||
|
||||
Then generate + translate:
|
||||
|
||||
6. `bun run extract` creates `src/locales/fr/messages.po` (every msgid, empty
|
||||
msgstr).
|
||||
7. Translate via a chunked agent workflow (this repo's proven recipe):
|
||||
- Split en.po entry blocks (split on blank lines, skip header) into ~60-entry
|
||||
chunks; one sonnet agent per chunk RETURNS translated entries (never let
|
||||
parallel agents edit one .po). Validate each returned chunk by msgid count;
|
||||
retry failures once.
|
||||
- Merge by msgid back into the locale .po. Match msgids by exact bytes —
|
||||
watch non-breaking spaces (\xa0) in msgids, which agents normalize away;
|
||||
patch those few by hand.
|
||||
- Agent rules: msgstr single-line, ICU placeholders/plural keywords and
|
||||
`<0>` tags preserved (translate only human words inside branches; plural
|
||||
categories follow the target language's CLDR set), FLXN/Flexxon/Spotify
|
||||
untranslated, casual sporty tone, register decided up front (tú/du/です・ます).
|
||||
8. `bun run i18n:check` must pass (0 missing). Optionally run per-locale
|
||||
native-reviewer agents over the full .po (fidelity, register, glossary
|
||||
consistency, ICU integrity) and apply their FIX lines.
|
||||
9. `bunx tsc --noEmit && bun run build`; confirm the new locale appears as its
|
||||
own lazy `messages-*.js` chunk in dist/client/assets.
|
||||
10. Manual check: switch language in Settings (persists to SuperTokens
|
||||
metadata), confirm UI + calendar + SMS behavior.
|
||||
|
||||
# Removing a language
|
||||
|
||||
Reverse of the above: delete from the five locale-set sites (skip Twilio if it
|
||||
was never listed), `rm -rf src/locales/<code>`, drop the dayjs import, then
|
||||
`bun run i18n:check` + tsc. Users with the removed locale saved in metadata
|
||||
fall back to English automatically via `resolveLocale`.
|
||||
|
||||
Fallback semantics: untranslated entries render English (msgid); unauth
|
||||
visitors get Accept-Language detection (SSR first paint on public routes is
|
||||
English, corrected after hydration); authed users get their saved locale
|
||||
server-rendered.
|
||||
Reference in New Issue
Block a user