I18n Localization System
All-in-one skill covering internationalization, localization, patterns, detecting. Includes structured workflows, validation checks, and reusable patterns for development.
Internationalization & Localization Skill
A Claude Code skill for implementing i18n and l10n in web applications — covering translation management, locale-aware formatting, RTL support, pluralization, and content delivery workflows.
When to Use This Skill
Choose this skill when:
- Adding multi-language support to an existing application
- Setting up i18n infrastructure for a new project
- Handling date, number, and currency formatting across locales
- Implementing RTL (right-to-left) layout support
- Managing translation files and workflows
- Configuring locale detection and switching
Consider alternatives when:
- Your app will only ever serve one language
- You need machine translation (use a translation API)
- You need content management across languages (use a headless CMS)
Quick Start
# Install i18n library (Next.js example) npm install next-intl # Or for React without Next.js npm install i18next react-i18next
// messages/en.json { "common": { "welcome": "Welcome, {name}!", "items": "{count, plural, =0 {No items} one {1 item} other {{count} items}}", "lastUpdated": "Last updated {date, date, medium}" }, "auth": { "login": "Sign in", "logout": "Sign out", "signup": "Create account" } } // messages/es.json { "common": { "welcome": "Bienvenido, {name}!", "items": "{count, plural, =0 {Sin elementos} one {1 elemento} other {{count} elementos}}", "lastUpdated": "Actualizado {date, date, medium}" }, "auth": { "login": "Iniciar sesion", "logout": "Cerrar sesion", "signup": "Crear cuenta" } }
Core Concepts
i18n Building Blocks
| Concept | Purpose | Example |
|---|---|---|
| Message Catalog | Store translations by key | en.json, es.json, ja.json |
| ICU Message Format | Handle plurals, gender, select | {count, plural, one {# item} other {# items}} |
| Locale Detection | Determine user's language | Browser header, URL path, cookie |
| Number Formatting | Locale-aware numbers | 1,234.56 (en) vs 1.234,56 (de) |
| Date Formatting | Locale-aware dates | 3/13/2026 (en-US) vs 13/03/2026 (en-GB) |
| RTL Support | Right-to-left languages | Arabic, Hebrew layout direction |
Formatting with Intl API
// Number formatting new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }) .format(1234.56); // "1.234,56 €" new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }) .format(1234); // "¥1,234" // Date formatting new Intl.DateTimeFormat('en-US', { dateStyle: 'long' }) .format(new Date()); // "March 13, 2026" new Intl.DateTimeFormat('fr-FR', { dateStyle: 'long' }) .format(new Date()); // "13 mars 2026" // Relative time new Intl.RelativeTimeFormat('en', { numeric: 'auto' }) .format(-1, 'day'); // "yesterday"
Next.js i18n Setup
// i18n.ts import { getRequestConfig } from 'next-intl/server'; export default getRequestConfig(async ({ locale }) => ({ messages: (await import(`./messages/${locale}.json`)).default })); // Component usage import { useTranslations } from 'next-intl'; export function Header() { const t = useTranslations('common'); return <h1>{t('welcome', { name: 'Sarah' })}</h1>; }
Configuration
| Parameter | Type | Default | Description |
|---|---|---|---|
default_locale | string | "en" | Fallback locale |
supported_locales | array | ["en"] | List of supported language codes |
detection_order | array | ["path", "cookie", "header"] | Locale detection priority |
fallback_strategy | string | "default" | Missing translation: default, key, empty |
namespace_separator | string | "." | Separator for nested translation keys |
rtl_locales | array | ["ar", "he", "fa"] | RTL language codes |
date_format | string | "medium" | Default date format style |
number_format | string | "decimal" | Default number format style |
Best Practices
-
Use ICU MessageFormat for all translatable strings — ICU handles pluralization, gender, and select logic within the message itself, so translators can adapt grammar without code changes.
-
Never concatenate translated strings —
t('hello') + ' ' + t('world')breaks in languages with different word order; use a single key with variables instead:t('greeting', { name }). -
Use the native
IntlAPI for dates and numbers — don't write custom formatting functions;Intl.NumberFormatandIntl.DateTimeFormathandle locale-specific formatting correctly. -
Store locale in the URL path, not just a cookie — URL-based locale (
/en/about,/es/about) is SEO-friendly and shareable; cookie-only locale is invisible to search engines. -
Extract translation keys during build — use tools like
i18next-parserto automatically find allt()calls and generate a list of keys needing translation, preventing missing translations.
Common Issues
Missing translations show raw keys in production — Set fallback_strategy: "default" to show the default locale's translation instead of the key. Add a CI check that compares key counts between locale files.
Pluralization doesn't work for all languages — English has 2 plural forms, but Arabic has 6 and Chinese has 1. Use ICU plural rules which handle all languages correctly: {count, plural, zero {...} one {...} two {...} few {...} many {...} other {...}}.
RTL layout breaks existing CSS — Use CSS logical properties (margin-inline-start instead of margin-left, padding-inline-end instead of padding-right) so layouts automatically mirror for RTL languages.
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
Full-Stack Code Reviewer
Comprehensive code review skill that checks for security vulnerabilities, performance issues, accessibility, and best practices across frontend and backend code.
Test Suite Generator
Generates comprehensive test suites with unit tests, integration tests, and edge cases. Supports Jest, Vitest, Pytest, and Go testing.
Pro Architecture Workspace
Battle-tested skill for architectural, decision, making, framework. Includes structured workflows, validation checks, and reusable patterns for development.