3.0 KiB
3.0 KiB
name, description
| name | description |
|---|---|
| add-language | 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:
src/lib/i18n/index.ts—SUPPORTED_LOCALES+LOCALE_LABELS(label in the language itself, no region clarifier:fr: "Français").lingui.config.ts—locales.src/lib/mantine/mantine-provider.tsx—DAYJS_LOCALEmap + the matchingimport 'dayjs/locale/fr'(calendar month/weekday names come from dayjs; without this, calendars stay English).src/lib/i18n/meta.ts—OG_LOCALE_BY_LOCALE(fr → fr_FR).src/lib/twilio/index.ts—TWILIO_VERIFY_LOCALESONLY 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:
bun run extractcreatessrc/locales/fr/messages.po(every msgid, empty msgstr).- 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/です・ます).
bun run i18n:checkmust 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.bunx tsc --noEmit && bun run build; confirm the new locale appears as its own lazymessages-*.jschunk in dist/client/assets.- 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.