# J4flmao Agent Skills Frontend Internationalization

> Frontend Internationalization (i18n)

- Skill: `tomevault-io/j4flmao-agent-skills-frontend-internationalization` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/j4flmao-agent-skills-frontend-internationalization`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/j4flmao-agent-skills-frontend-internationalization/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/j4flmao-agent-skills-frontend-internationalization

---


# Frontend Internationalization (i18n)

## Purpose
Deliver multi-locale frontends with proper locale detection, resource loading, ICU message formatting, pluralization, date/number formatting, and full RTL layout support. The right library is chosen per framework. Translation files are kept separate from application logic.

## Agent Protocol

### Trigger
Exact phrases: "i18n", "internationalization", "localization", "locale switching", "RTL", "i18next", "react-intl", "vue-i18n", "translation", "language selector", "formatjs", "pluralization", "bidirectional text", "locale detection".

### Input Context
- Framework (React, Vue, Angular, Svelte, vanilla)
- Locales required (e.g., en, fr, ar, he)
- Existing i18n library or preference
- SSR vs client-only rendering
- Dynamic vs build-time locale loading
- RTL support needed

### Output Artifact
Complete i18n setup: library config, resource structure, locale switching mechanism, RTL styles, and usage patterns.

### Response Format
```
## Strategy
<library, locale-loading, RTL-approach>

## Setup
<config, resource-imports>

## Usage
<components, hooks, format-patterns>

## RTL
<layout-switch, css-logical-properties>

—
Compression footer: frontend-i18n/v1 | locales: <count> | lib: <selected> | rtl: <bool>
```

No preamble. No postamble. No explanations. No filler/hedging/transitions. Compress output — why use many token when few do trick.

### Completion Criteria
- [ ] Locale resources loaded (dynamic or static) without affecting TTFB
- [ ] Locale switching works without full page reload
- [ ] ICU message format used for pluralization and interpolation
- [ ] Dates, numbers, currencies formatted per locale
- [ ] RTL layout switches correctly with CSS logical properties
- [ ] Language direction attribute updates on the `<html>` element
- [ ] Translation key fallback chain configured (locale → fallback locale)
- [ ] SSR locale detection sends correct language to client

### Max Response Length
4096 tokens

## Workflow

### 1. Library Selection
| Framework | Library | Notes |
|-----------|---------|-------|
| React | react-i18next (i18next) | Most mature, full feature set |
| React | react-intl (FormatJS) | ICU message syntax, smaller bundle |
| Vue 2/3 | vue-i18n | Official Vue i18n solution |
| Angular | @angular/localize | Built-in Angular i18n |
| Svelte | svelte-i18n | Lightweight, reactive |
| Vanilla | i18next | Framework-agnostic |

Prefer i18next for cross-framework projects or when full feature set is needed. Prefer FormatJS for React projects that need ICU message syntax and smaller bundle size.

### 2. Resource Structure
```
locales/
├── en/
│   ├── common.json
│   ├── auth.json
│   └── errors.json
├── fr/
│   ├── common.json
│   ├── auth.json
│   └── errors.json
└── ar/
    ├── common.json
    ├── auth.json
    └── errors.json
```
Namespaced translation files. Lazy-load namespaces on demand. Each namespace is a flat JSON file with dot-separated keys.

### 3. Locale Detection & Persistence
```typescript
// Priority: URL > localStorage > cookie > navigator.language > fallback
import i18n from 'i18next'
import LanguageDetector from 'i18next-browser-languagedetector'

i18n.use(LanguageDetector).init({
  detection: {
    order: ['localStorage', 'navigator', 'htmlTag'],
    caches: ['localStorage'],
  },
  fallbackLng: 'en',
  interpolation: { escapeValue: false },
})
```

### 4. Translation Usage
```typescript
// Key-based translation with interpolation
t('auth.welcome', { name: 'Alice' })
// → "Welcome, Alice!"

// Pluralization
t('common.items', { count: items.length })
// count=0 → "No items"
// count=1 → "1 item"
// count=5 → "5 items"

// With context
t('common.status', { context: status })
// status='online' → "User is online"
// status='offline' → "User is offline"
```

### 5. ICU Message Format (FormatJS)
```typescript
import { FormattedMessage, useIntl } from 'react-intl'

// Component
<FormattedMessage
  defaultMessage="{name} has {numPhotos, plural, =0 {no photos} =1 {one photo} other {# photos}}"
  values={{ name: 'Alice', numPhotos: 3 }}
/>

// Hook
const { formatMessage } = useIntl()
formatMessage({ defaultMessage: 'Hello {name}' }, { name: 'Bob' })
```

### 6. RTL Support
```typescript
// Detect direction from locale
const isRTL = ['ar', 'he', 'fa', 'ur'].includes(locale)
document.documentElement.dir = isRTL ? 'rtl' : 'ltr'
document.documentElement.lang = locale
```

Prefer CSS logical properties over hardcoded left/right:
```css
/* NOT THIS */
.sidebar { margin-left: 16px; text-align: left; }

/* THIS */
.sidebar { margin-inline-start: 16px; text-align: start; }
```

Logical properties automatically flip in RTL mode: `margin-inline-start` → right margin in RTL, `padding-inline-end` → left padding in RTL, `border-inline-start` → right border in RTL, `inset-inline-start` → right positioning in RTL.

### 7. Date & Number Formatting
```typescript
// i18next
new Date().toLocaleDateString(locale, { dateStyle: 'long' })
new Intl.NumberFormat(locale, { style: 'currency', currency: 'EUR' }).format(amount)

// FormatJS
import { FormattedDate, FormattedNumber } from 'react-intl'

<FormattedDate value={date} dateStyle="long" />
<FormattedNumber value={price} style="currency" currency="USD" />
<FormattedNumber value={0.9} style="percent" />
```

### 8. SSR Locale Detection
```typescript
// Next.js i18n (simpler approach — use middleware)
// Or accept-language header parsing
import acceptLanguage from 'accept-language'
acceptLanguage.languages(['en', 'fr', 'ar'])

export function getLocaleFromHeaders(request: Request): string {
  const acceptLang = request.headers.get('accept-language') || ''
  return acceptLanguage.parse(acceptLang)[0] || 'en'
}
```

### 9. Lazy Loading
```typescript
i18n.use(initReactI18next).init({
  resources: {}, // start empty
  partialBundledLanguages: true,
})

// Load namespace on demand
async function loadNamespace(locale: string, ns: string) {
  const resources = await import(`./locales/${locale}/${ns}.json`)
  i18n.addResourceBundle(locale, ns, resources)
}
```

### 10. Testing with i18n
```typescript
import { render } from '@testing-library/react'
import { I18nextProvider } from 'react-i18next'
import i18n from './i18n-test-config' // test-only config

function renderWithI18n(ui: React.ReactElement) {
  return render(<I18nextProvider i18n={i18n}>{ui}</I18nextProvider>)
}
```

## Rules
1. Never embed user-facing strings directly in components — always use translation keys.
2. Translation keys follow a namespaced dot notation: `namespace.key.subkey`.
3. Use ICU message format for pluralization, select, and ordinal rules.
4. Never use CSS `left`/`right` properties — use CSS logical properties (`inline-start`/`inline-end`).
5. HTML dir attribute and lang attribute are always in sync with current locale.
6. Lazy-load translation files — never bundle all locales in the main chunk.
7. Fallback chain always configured: target locale → fallback locale → key itself.
8. Locale detection never relies solely on browser `navigator.language` — persist user choice.
9. Numbers, dates, and currencies are formatted with `Intl` — never hardcoded.
10. Translation interpolation escapes HTML by default to prevent XSS.

## References
- `references/i18n-libraries.md` — i18next, react-intl, vue-i18n, FormatJS, Angular i18n, setup patterns, lazy loading
- `references/rtl-support.md` — CSS logical properties, dir attribute, RTL testing, layout adaptation

## Handoff
No artifact produced unless requested.
Next skill: `frontend-accessibility` — RTL a11y overlaps with i18n, pass locale direction config.
Carry forward: locale list, RTL requirement, i18n library, lazy loading strategy.

---
> Source: [j4flmao/agent-skills](https://github.com/j4flmao/agent-skills) — distributed by [TomeVault](https://tomevault.io).
<!-- tomevault:4.0:skill_md:2026-05-24 -->

