v1.2.0 to v1.2.0

3 added, 3 removed. Audit A to A.

---
name: i18n-date-patterns
license: MIT
compatibility: "Claude Code 2.1.251+."
description: Implements internationalization (i18n) in React applications. Covers user-facing strings, date/time handling, locale-aware formatting, ICU MessageFormat, and RTL support. Use when building multilingual UIs or formatting dates/currency.
context: inherit
agent: frontend-ui-developer
version: 1.2.0
author: Yonatan Gross
tags: [i18n, internationalization, dayjs, dates, react-i18next, localization, rtl, useTranslation, useFormatting, ICU, Trans]
user-invocable: false
disable-model-invocation: true
complexity: low
persuasion-type: reference
effort: low
targets:
- library: react-i18next
version: ">=13.0.0"
- library: dayjs
version: ">=1.11.0"
model: haiku
metadata:
category: document-asset-creation
allowed-tools:
- Read
- Glob
- Grep
- WebFetch
- WebSearch
path_patterns: ["**/i18n/**", "**/locales/**", "**/translations/**", "*.locale.*"]
---
# i18n and Localization Patterns
## Overview
This skill provides comprehensive guidance for implementing internationalization in React applications. It ensures ALL user-facing strings, date displays, currency, lists, and time calculations are locale-aware.
**When to use this skill:**
- Adding ANY user-facing text to components
- Formatting dates, times, currency, lists, or ordinals
- Implementing complex pluralization
- Embedding React components in translated text
- Supporting RTL languages (Hebrew, Arabic)
- **Bundled Resources** (load with `Read("${CLAUDE_PLUGIN_ROOT}/skills/i18n-date-patterns/<path>")`):
+ **Bundled Resources** (load with `Read("<path>")`):
- `references/formatting-utilities.md` - useFormatting hook API reference
- `references/ork-delta.md` - House decisions and working config that upstream docs do not carry
- `checklists/i18n-checklist.md` - Implementation and review checklist
- `examples/component-i18n-example.md` - Complete component example
**Canonical Reference:** See `docs/i18n-standards.md` for the full i18n standards document.
---
## Core Patterns
### 1. useTranslation Hook (All UI Strings)
Every visible string MUST use the translation function:
```tsx
import { useTranslation } from 'react-i18next';
function MyComponent() {
const { t } = useTranslation(['patients', 'common']);
return (
<div>
<h1>{t('patients:title')}</h1>
<button>{t('common:actions.save')}</button>
</div>
);
}
```
### 2. useFormatting Hook (Locale-Aware Data)
All locale-sensitive formatting MUST use the centralized hook:
```tsx
import { useFormatting } from '@/hooks';
function PriceDisplay({ amount, items }) {
const { formatILS, formatList, formatOrdinal } = useFormatting();
return (
<div>
<p>Price: {formatILS(amount)}</p> {/* ₪1,500.00 */}
<p>Items: {formatList(items)}</p> {/* "a, b, and c" */}
<p>Position: {formatOrdinal(3)}</p> {/* "3rd" */}
</div>
);
}
```
- Load `Read("${CLAUDE_PLUGIN_ROOT}/skills/i18n-date-patterns/references/formatting-utilities.md")` for the complete API.
+ Load `Read("references/formatting-utilities.md")` for the complete API.
### 3. Date Formatting
All dates MUST use the centralized `@/lib/dates` library:
```tsx
import { formatDate, formatDateShort, calculateWaitTime } from '@/lib/dates';
const date = formatDate(appointment.date); // "Jan 6, 2026"
const waitTime = calculateWaitTime('09:30'); // "15 min"
```
### 4. ICU MessageFormat (Complex Plurals)
Use ICU syntax in translation files for pluralization:
```json
{
"patients": "{count, plural, =0 {No patients} one {# patient} other {# patients}}"
}
```
```tsx
t('patients', { count: 5 }) // → "5 patients"
```
House rules for plurals live in `rules/i18n-icu-plurals.md`. For the full ICU grammar
see the upstream table below.
### 5. Trans Component (Rich Text)
For embedded React components in translated text:
```tsx
import { Trans } from 'react-i18next';
<Trans
i18nKey="richText.welcome"
values={{ name: userName }}
components={{ strong: <strong /> }}
/>
```
House rules for `<Trans>` live in `rules/i18n-trans-component.md`; the plural-plus-rich-text
ordering constraint lives in `references/ork-delta.md`. For the full component API see the
upstream table below.
---
## Upstream coverage (do not restate)
These topics are owned by first-party docs. Read them there instead of re-deriving them here.
| Topic | First-party source | House subset kept here |
|-------|--------------------|------------------------|
| ICU plural, select, selectordinal, offset and nested message grammar | https://formatjs.github.io/docs/core-concepts/icu-syntax/ and https://unicode-org.github.io/icu/userguide/format_parse/messages/ | `rules/i18n-icu-plurals.md` keeps the house subset in full: no ternary pluralization, the mandatory `other` arm, `=0` for zero states, Hebrew dual and Arabic categories |
| Which plural categories a given locale actually has | https://cldr.unicode.org/index/cldr-spec/plural-rules | none, read upstream |
| ICU number skeletons inside a message (`::currency/ILS`) | https://unicode-org.github.io/icu/userguide/format_parse/numbers/skeletons.html | `references/ork-delta.md` keeps only the ILS skeleton decision |
| In-message date and time forms (`{date, date, medium}`) and `offset:` plurals | https://unicode-org.github.io/icu/userguide/format_parse/messages/ | nothing; fetch it upstream |
| `<Trans>` API: named vs indexed tags, self-closing tags, `TransProps` typing | https://react.i18next.com/latest/trans-component | `rules/i18n-trans-component.md` keeps the house subset in full: never split a sentence across `t()` calls, never `dangerouslySetInnerHTML`, prefer named tags over indexed |
| Wiring the ICU parser into i18next | https://github.com/i18next/i18next-icu | `references/ork-delta.md` keeps the decision and why suffix keys are not enough |
| `Intl.ListFormat` primitive behind `useFormatting` | https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat | `references/formatting-utilities.md` keeps the house hook API |
| `Intl.NumberFormat` primitive behind `useFormatting` | https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat | `references/formatting-utilities.md` keeps the house hook API |
---
## Translation File Structure
```
frontend/src/i18n/locales/
├── en/
│ ├── common.json # Shared: actions, status, time
│ ├── patients.json # Patient-related strings
│ ├── dashboard.json # Dashboard strings
│ ├── owner.json # Owner portal strings
│ └── invoices.json # Invoice strings
└── he/
└── (same structure)
```
---
## Anti-Patterns (FORBIDDEN)
```typescript
// ❌ NEVER hardcode strings
<h1>מטופלים</h1> // Use t('patients:title')
<button>Save</button> // Use t('common:actions.save')
// ❌ NEVER use .join() for lists
items.join(', ') // Use formatList(items)
// ❌ NEVER hardcode currency
"₪" + price // Use formatILS(price)
// ❌ NEVER use new Date() for formatting
new Date().toLocaleDateString() // Use formatDate() from @/lib/dates
// ❌ NEVER use inline plural logic
count === 1 ? 'item' : 'items' // Use ICU MessageFormat
// ❌ NEVER leave console.log in production
console.log('debug') // Remove before commit
// ❌ NEVER use dangerouslySetInnerHTML for i18n
dangerouslySetInnerHTML // Use <Trans> component
```
---
## Quick Reference
| Need | Solution |
|------|----------|
| UI text | `t('namespace:key')` from `useTranslation` |
| Currency | `formatILS(amount)` from `useFormatting` |
| Lists | `formatList(items)` from `useFormatting` |
| Ordinals | `formatOrdinal(n)` from `useFormatting` |
| Dates | `formatDate(date)` from `@/lib/dates` |
| Plurals | ICU MessageFormat in translation files |
| Rich text | `<Trans>` component |
| RTL check | `isRTL` from `useFormatting` |
---
## Checklist
- Load `Read("${CLAUDE_PLUGIN_ROOT}/skills/i18n-date-patterns/checklists/i18n-checklist.md")` for complete implementation and review checklists.
+ Load `Read("checklists/i18n-checklist.md")` for complete implementation and review checklists.
---
## Integration with Agents
### Frontend UI Developer
- Uses all i18n patterns for components
- References this skill for formatting
- Ensures no hardcoded strings
### Code Quality Reviewer
- Checks for anti-patterns (`.join()`, `console.log`, etc.)
- Validates translation key coverage
- Ensures RTL compatibility
---
**Skill Version**: 1.2.0
**Last Updated**: 2026-01-06
**Maintained by**: Yonatan Gross
## Related Skills
- `ork:testing-e2e` - E2E testing patterns including accessibility testing for i18n
- `ork:react-server-components-framework` - Server-side locale detection and RSC i18n patterns
- `ork:accessibility` - RTL-aware focus management for bidirectional UI navigation
## Key Decisions
| Decision | Choice | Rationale |
|----------|--------|-----------|
| Translation Library | react-i18next | React-native hooks, namespace support, ICU format |
| Date Library | dayjs | Lightweight, locale plugins, immutable API |
| Message Format | ICU MessageFormat | Industry standard, complex plural/select support |
| Locale Storage | Per-namespace JSON | Code-splitting, lazy loading per feature |
| RTL Detection | CSS logical properties | Native browser support, no JS overhead |
## Capability Details
### translation-hooks
**Keywords:** useTranslation, t(), i18n hook, translation hook
**Solves:**
- Translate UI strings with useTranslation
- Implement namespaced translations
- Handle missing translation keys
### formatting-hooks
**Keywords:** useFormatting, formatCurrency, formatList, formatOrdinal
**Solves:**
- Format currency values with locale
- Format lists with proper separators
- Handle ordinal numbers across locales
### icu-messageformat
**Keywords:** ICU, MessageFormat, plural, pluralization
**Solves:**
- Apply the house Hebrew plural-category decision (see `references/ork-delta.md`)
- ICU `select`, gender forms and nested message grammar are routed upstream (see Upstream coverage)
- Build complex message patterns
### date-time-formatting
**Keywords:** date format, time format, dayjs, locale date, calendar
**Solves:**
- Format dates with dayjs and locale
- Handle timezone-aware formatting
- Build calendar components with i18n
### rtl-support
**Keywords:** RTL, right-to-left, hebrew, arabic, direction
**Solves:**
- Support RTL languages like Hebrew
- Handle bidirectional text
- Configure RTL-aware layouts
### trans-component
**Keywords:** Trans, rich text, embedded JSX, interpolation
**Solves:**
- Embed React components in translations
- Handle rich text formatting
- Implement safe HTML in translations