Production-grade i18n/l10n patterns for React, Vue, Angular, Next.js, and Node.js. Covers library selection (i18next/react-i18next, FormatJS/react-intl, next-intl, vue-i18n, @angular/localize, Lingui, typesafe-i18n), ICU message format, RTL support, locale routing/detection, TMS integration, string extraction, and CI/CD translation workflows. Use when setting up or debugging localisation in a codebase.
Use this skill for production web-app i18n and l10n: library choice, message catalogs, ICU usage, locale routing, translation workflow, RTL, and release gates. The goal is not just translated strings. The goal is locale-safe product behavior.
| Need | Starting Direction |
|------|--------------------|
| React or general flexibility | i18next / react-i18next |
| ICU-first catalogs | react-intl / FormatJS |
| Vue | vue-i18n |
| Angular | @angular/localize |
| Next.js App Router | next-intl |
| smaller bundle bias | Lingui |
| stronger generated wrappers | typesafe-i18n only when deliberate |
marketing-seomarketing-geo-localizationreferences/accessibility-i18n.mdmarketing-seo instead.Localisation task
-> Identify platform, source-of-truth catalog, and affected locales
-> Choose key, ICU, formatting, and fallback strategy
-> Patch durable source, not only generated output
-> Check missing keys, plural rules, RTL, and text expansion
-> Run generation or validation scripts
-> Report locale coverage and residual translation risk
| Situation | Library | Why |
|---|---|---|
| React / TypeScript, general flexibility | i18next + react-i18next | Best selector API and plugin ecosystem |
| ICU-first catalogs, FormatJS tooling already in use | react-intl | Tightest ICU integration; FormatJS extract/compile pipeline |
| Next.js App Router | next-intl | Built for RSC + App Router; automatic locale routing |
| Vue | vue-i18n | Framework-native; best Vue tooling integration |
| Angular | @angular/localize | Build-time extraction and AOT compilation |
| Smaller bundle budget | Lingui | Smallest runtime; macro-based message extraction |
| Team explicitly wants generated type wrappers | typesafe-i18n | Full key-type safety; high maintenance model |
Do not choose by popularity alone. Choose by routing model, extraction needs, ICU expectations, and team maintenance habits.
MF2 is standardized at the syntax level in Unicode's LDML spec (stabilized through LDML 47-48), which makes it tempting to treat as "the new ICU." Do not migrate production catalogs to it as of mid-2026: ICU's own reference implementations are still draft/technology-preview status, and none of react-intl/FormatJS, i18next, vue-i18n, or Lingui has shipped a production MF2 migration path, and no mainstream TMS round-trips it. Keep using MessageFormat 1 / ICU syntax (documented in references/icu-message-format.md) and re-check adoption status before recommending a switch — this is a common "the spec is final, so it must be safe to use" misdiagnosis.
dir="rtl" where required| Gate | Failure condition | Remediation |
|---|---|---|
| Mixed-language output | Any locale-routed page renders keys from a different locale | Missing-key CI check catches before merge |
| Missing-key bleed | Core UX or marketing route shows a key ID or raw fallback string | Extraction + catalog diff in CI pipeline |
| Machine translation on release path | MT output inserted without glossary, tone, or reviewer gate | Add human review step for all customer-visible locales |
| Locale switch drops state or breaks navigation | User changes locale and loses cart, form, or route state | Centralize locale state; separate from route/cookie |
| RTL launched without visual validation | Arabic/Hebrew/Farsi layout broken on launch | Require visual pass on one RTL locale before release |
| EU-market product ships accessible markup but only one language | Passes WCAG in English yet still fails the combined EAA + consumer-language bar in non-English EU markets | Review accessibility and localisation together for EU-facing surfaces; see references/accessibility-i18n.md |
| Trap | Prevention |
|---|---|
| Keys drift between extraction, TMS, and runtime — fallback "works" but locale is broken | Run missing-key checks in CI; diff extraction output against TMS catalog before release |
| Visible strings translated, but validation messages / metadata / emails / JSON-LD left in English | Enumerate all locale surfaces (UI, email, SEO, legal) at project start; treat each as a separate test gate |
| String concatenation for grammar-sensitive or gendered copy | Use ICU {count, plural, ...} / {gender, select, ...}; never "Hello " + name |
| Only Latin-script locales tested | Require one long-string locale (de/ru) and one non-Latin (ja/ar) before "complete" |
| Locale persisted separately in route, cookie, and client state with no precedence rule | Define precedence order once: user preference > URL route > cookie > Accept-Language > default locale |
| Machine translation shipped without glossary or review | Require glossary, tone rules, and human review gate for all customer-visible content |
| Plural category count assumed from memory (e.g. "French is just one/other like English") | CLDR revises per-language category counts over time (French now has one, many, other); verify against the current CLDR plural rules chart, don't hardcode from a prior project |
| Translated content rendered as raw HTML (v-html, dangerouslySetInnerHTML, ICU HTML tags) with no CSP/Trusted Types | Real XSS advisories exist for this exact pattern in both vue-i18n (CVE-2025-53892) and Angular's i18n pipeline (CVE-2026-27970) — treat translation-file write access as privileged and pin patched library versions |
| Anti-pattern | Correct approach |
|---|---|
| English as silent fallback on locale-routed pages | Fail visibly in CI or preview when a key is missing in a non-default locale |
| Business logic encoded in translation keys | Keys represent UI text; business logic belongs in code |
| Translations split by developer convenience | Split by stable product domain and runtime loading boundary |
| CSS directional properties (left, right) patched per-view for RTL | Use CSS logical properties (inline-start, inline-end) from the start |
| Each product surface (marketing, support, product) runs separate locale logic | Centralize fallback, formatting, and detection in one shared locale layer |
For large locale catalogs or mixed-language incidents:
Use references/ops-runbook.md for the detailed triage procedure.
python3 scripts/check_urls.pypython3 scripts/check_examples.pymarketing-seoBefore applying this skill on a non-trivial task, read learnings.consolidated.md in this directory (and learnings.md if present).
After applying it, if you encountered a pattern worth remembering, a mistake worth preventing, or a domain fact that surprised you, append one dated bullet to learnings.md via agents-skills-feedback-loop/scripts/append_learning.py. Do not modify SKILL.md itself.
npx skills add vasilyu1983/software-localisation下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer