97 lines
4.2 KiB
Markdown
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.
|