i18n

SKILL.md

Internationalization (i18n)

Build applications that speak your users' language


When to Use This Skill

Use this skill when:

  • Implementing multi-language support
  • Formatting dates/numbers for different locales
  • Handling RTL languages
  • Managing translation files

Critical Patterns

Pattern 1: Basic Translation

When: Displaying translated text

Good:

// useTranslations hook
import { useTranslations } from 'next-intl';

export default function HomePage() {
  const t = useTranslations('homepage');

  return (
    <div>
      <h1>{t('title')}</h1>
      <p>{t('subtitle')}</p>
    </div>
  );
}

// Translation file
// messages/en.json
{
  "homepage": {
    "title": "Welcome to Our Store",
    "subtitle": "Find the best products"
  }
}

Why: Centralized translations make it easy to support multiple languages.


Pattern 2: Variables in Translations

When: Including dynamic values

Good:

{
  "welcome": "Welcome, {username}!",
  "itemCount": "You have {count} items"
}
<p>{t('welcome', { username: 'Alice' })}</p>
<p>{t('itemCount', { count: 5 })}</p>

Why: ICU syntax allows flexible variable interpolation.


Pattern 3: Pluralization

When: Handling singular/plural forms

Good:

{
  "items": "{count, plural, =0 {No items} =1 {1 item} other {# items}}"
}
<p>{t('items', { count: 0 })}</p>  // "No items"
<p>{t('items', { count: 1 })}</p>  // "1 item"
<p>{t('items', { count: 5 })}</p>  // "5 items"

Why: Different languages have different pluralization rules.


Pattern 4: Date/Number Formatting

When: Displaying locale-specific formats

Good:

import { useFormatter } from 'next-intl';

export default function EventDate({ date, amount }) {
  const format = useFormatter();

  return (
    <div>
      {/* Date: "January 15, 2024" (en), "15 janvier 2024" (fr) */}
      <p>{format.dateTime(date, { dateStyle: 'long' })}</p>

      {/* Currency: "$99.99" (en-US), "99,99 €" (de-DE) */}
      <p>{format.number(amount, {
        style: 'currency',
        currency: 'USD'
      })}</p>
    </div>
  );
}

Why: Date and number formats vary by locale.


Pattern 5: RTL Support

When: Supporting Arabic, Hebrew, etc.

Good:

/* Use logical properties */
.card {
  margin-inline-start: 1rem;  /* Left in LTR, right in RTL */
  padding-inline-end: 2rem;
}

/* Manual RTL handling */
[dir='rtl'] .arrow {
  transform: scaleX(-1);
}
// Set dir attribute
<html lang={locale} dir={locale === 'ar' ? 'rtl' : 'ltr'}>

Why: RTL languages need flipped layouts.


Best Practices

Do's:

  • ✅ Extract all user-facing text to translation files
  • ✅ Use ICU syntax for complex messages
  • ✅ Test with long German text (30% longer)
  • ✅ Test RTL languages
  • ✅ Format dates/numbers with locale-aware formatters
  • ✅ Provide context in translation keys

Don'ts:

  • ❌ Don't hardcode strings
  • ❌ Don't concatenate translations
  • ❌ Don't use locale for business logic
  • ❌ Don't forget text expansion

Code Examples

Example 1: Basic Translation with Variables

// messages/en.json
{
  "welcome": "Welcome, {username}!",
  "cartItems": "You have {count, plural, =0 {no items} =1 {1 item} other {# items}} in your cart"
}

// Component
import { useTranslations } from 'next-intl';

export default function Header({ username, cartCount }: HeaderProps) {
  const t = useTranslations();

  return (
    <header>
      <h1>{t('welcome', { username })}</h1>
      <p>{t('cartItems', { count: cartCount })}</p>
    </header>
  );
}

Example 2: Locale-Aware Date and Number Formatting

import { useFormatter } from 'next-intl';

export default function ProductCard({ product }: ProductCardProps) {
  const format = useFormatter();

  return (
    <div>
      <h3>{product.name}</h3>
      <p>{format.number(product.price, {
        style: 'currency',
        currency: 'USD'
      })}</p>
      <time>{format.dateTime(product.releaseDate, {
        year: 'numeric',
        month: 'long',
        day: 'numeric'
      })}</time>
    </div>
  );
}

For comprehensive examples and detailed implementations, see the references/ folder.


Progressive Disclosure

For detailed implementations:


References


Maintained by dsmj-ai-toolkit

Weekly Installs
3
First Seen
Feb 16, 2026
Installed on
gemini-cli3
github-copilot3
codex3
amp3
kimi-cli3
opencode3