Skills/i18n-l10n-standards/SKILL.md

97 lines
4.2 KiB
Markdown

---
name: i18n-l10n-standards
description: >-
Enforce internationalization (i18n), localization (l10n), and bidirectional layout standards (LTR/RTL).
Eliminates hardcoded strings, requires CSS logical properties (padding-inline, margin-inline),
type-safe translation schemas, and native browser Intl formatting.
---
# Internationalization (i18n), Localization (l10n) & Bidirectional Layouts
Ce skill impose les règles nécessaires pour concevoir des applications web multilingues et universellement adaptables. Il élimine le texte en dur dans les composants, impose les **propriétés logiques CSS** pour supporter nativement les écritures de droite à gauche (RTL comme l'arabe et l'hébreu) et standardise le formatage des données via l'API native `Intl`.
---
## 🎯 Déclencheurs d'Activation
Activez ce skill dès que :
1. Vous structurez une application multilingue (ex: français, anglais, espagnol, arabe).
2. Vous écrivez du balisage contenant du texte visible par l'utilisateur (interdiction de coder en dur).
3. Vous appliquez des marges, espacements ou alignements directionnels (`padding`, `margin`, `text-align`, `float`).
4. Vous formatez des prix, devises, pourcentages, dates ou durées relatives.
5. Vous configurez le routage multilingue (`/fr/`, `/en/`) et les balises SEO `hreflang`.
---
## 📐 1. Propriétés CSS Logiques (Inversion Automatique RTL)
Les classes physiques (`left`, `right`) cassent le design dès qu'une langue s'écrit de droite à gauche. Utilisez systématiquement les **propriétés logiques** :
| Classe Physique (Interdite) | Classe Logique Standard | Propriété CSS Sous-jacente |
| :--- | :--- | :--- |
| `pl-4` / `pr-4` | `ps-4` / `pe-4` | `padding-inline-start` / `padding-inline-end` |
| `ml-auto` | `ms-auto` | `margin-inline-start: auto` |
| `text-left` / `text-right` | `text-start` / `text-end` | `text-align: start` / `text-align: end` |
| `left-0` / `right-0` | `start-0` / `end-0` | `inset-inline-start: 0` / `inset-inline-end: 0` |
| `border-l` / `border-r` | `border-s` / `border-e` | `border-inline-start` / `border-inline-end` |
---
## 🌐 2. Dictionnaires de Traduction Typés (Zéro Chaîne en Dur)
Toutes les chaînes de texte doivent provenir d'un dictionnaire typé (ex: `next-intl`, `paraglide` ou format ICU) :
```tsx
import { useTranslations } from 'next-intl';
export const PricingHeader = () => {
const t = useTranslations('pricing');
return (
<div className="flex flex-col gap-2 text-start ps-4">
{/* Traduction avec interpolation sécurisée */}
<h1 className="text-3xl font-bold text-white">
{t('title')}
</h1>
<p className="text-sm text-white/70">
{t('subtitle', { count: 3 })}
</p>
</div>
);
};
```
---
## 💶 3. Formatage Natif via l'API Navigateur `Intl`
Ne formatez jamais manuellement des nombres ou des dates avec des expressions régulières ou des calculs maison. L'API native JavaScript standard `Intl` est calibrée par l'IETF :
```typescript
// Monnaies & Devises
export const formatCurrency = (amount: number, locale = 'fr-FR', currency = 'EUR') => {
return new Intl.NumberFormat(locale, {
style: 'currency',
currency,
}).format(amount);
};
// formatCurrency(1249.5, 'fr-FR', 'EUR') => "1 249,50 €"
// formatCurrency(1249.5, 'en-US', 'USD') => "$1,249.50"
// Dates Relatives ("il y a 2 heures", "hier")
export const formatRelativeTime = (value: number, unit: Intl.RelativeTimeFormatUnit, locale = 'fr-FR') => {
return new Intl.RelativeTimeFormat(locale, { numeric: 'auto' }).format(value, unit);
};
// formatRelativeTime(-1, 'day', 'fr-FR') => "hier"
```
---
## 📋 Checklist de Conformité i18n & RTL
- [ ] Aucune chaîne de texte visible n'est codée en dur dans les composants JSX.
- [ ] Les classes Tailwind directionnelles utilisent exclusivement les variantes logiques (`ps-*`, `pe-*`, `ms-*`, `me-*`, `start-*`, `end-*`).
- [ ] L'attribut `dir="rtl"` ou `dir="ltr"` est appliqué dynamiquement sur la balise `<html>`.
- [ ] Les prix, dates et pourcentages sont formatés via `Intl.NumberFormat` ou `Intl.DateTimeFormat`.
- [ ] Les balises `<link rel="alternate" hreflang="..." href="...">` sont présentes pour chaque variante linguistique.