IntlPull
Guide
16 min read

react-intl (FormatJS) : Le Guide Complet de l'Internationalisation React en 2026

Maîtrisez react-intl (FormatJS) pour l'i18n React. Tutoriel complet couvrant IntlProvider, FormattedMessage, la syntaxe ICU, les hooks et les meilleures pratiques de production.

IntlPull Team
IntlPull Team
03 Feb 2026, 11:44 AM [PST]
On this page
Summary

Maîtrisez react-intl (FormatJS) pour l'i18n React. Tutoriel complet couvrant IntlProvider, FormattedMessage, la syntaxe ICU, les hooks et les meilleures pratiques de production.

Réponse Rapide

react-intl est la liaison React pour FormatJS, fournissant le support du format de message ICU pour l'internationalisation. Installez avec npm install react-intl, enveloppez votre application avec <IntlProvider locale="en" messages={messages}>, puis utilisez <FormattedMessage id="greeting" /> ou le hook useIntl() pour afficher les traductions. Choisissez react-intl lorsque vous avez besoin d'une conformité ICU stricte ou d'un formatage de date/nombre intégré. Pour des besoins plus simples, react-i18next peut être plus facile.


Qu'est-ce que react-intl ?

react-intl fait partie de l'écosystème FormatJS, une implémentation officielle du Format de Message ICU pour JavaScript. Il fournit :

  • Format de Message ICU : Syntaxe standard de l'industrie pour les pluriels, le genre et les messages complexes
  • Formateurs intégrés : Dates, nombres, devises, temps relatif
  • Support TypeScript : Extraction de message et formatage type-safe
  • Testé en production : Utilisé par Yahoo, Microsoft, Airbnb

react-intl vs react-i18next

Fonctionnalitéreact-intlreact-i18next
Format de MessageICU (strict)JSON (flexible)
Taille Bundle~25KB~15KB
PlurielsSyntaxe ICUClés suffixées
FormateursIntégrésPlugin/manuel
Courbe d'ApprentissagePlus élevéePlus faible
TypeScriptExcellentExcellent

Choisissez react-intl quand :

  • Vous avez besoin d'une conformité ICU stricte
  • Votre équipe connaît la syntaxe ICU
  • Vous voulez un formatage de date/nombre intégré
  • Vous intégrez avec des outils de traduction qui utilisent ICU

Choisissez react-i18next quand :

  • Vous voulez une syntaxe plus simple
  • Vous avez besoin d'une taille de bundle plus petite
  • Votre équipe préfère les clés basées sur JSON

Installation

Terminal
1npm install react-intl
2# ou
3yarn add react-intl
4# ou
5pnpm add react-intl

Outils CLI Optionnels

Terminal
1# Extraire les messages du code
2npm install -D @formatjs/cli
3
4# Compiler les messages pour la production
5npm install -D @formatjs/cli

Configuration de Base

Étape 1 : Créer les Fichiers de Traduction

src/
├── lang/
│   ├── en.json
│   ├── es.json
│   └── fr.json
└── App.tsx

fr.json:

JSON
1{
2  "app.greeting": "Bienvenue sur notre application !",
3  "app.nav.home": "Accueil",
4  "app.nav.about": "À propos",
5  "app.buttons.submit": "Envoyer",
6  "app.buttons.cancel": "Annuler"
7}

Étape 2 : Configurer IntlProvider

TSX
1// src/App.tsx
2import { IntlProvider } from 'react-intl';
3import { useState } from 'react';
4
5import enMessages from './lang/en.json';
6import frMessages from './lang/fr.json';
7
8const messages: Record<string, Record<string, string>> = {
9  en: enMessages,
10  fr: frMessages,
11};
12
13function App() {
14  const [locale, setLocale] = useState('fr');
15
16  return (
17    <IntlProvider
18      locale={locale}
19      messages={messages[locale]}
20      defaultLocale="fr"
21      onError={(err) => {
22        if (err.code !== 'MISSING_TRANSLATION') {
23          console.error(err);
24        }
25      }}
26    >
27      <MainApp onLocaleChange={setLocale} />
28    </IntlProvider>
29  );
30}

Étape 3 : Utiliser FormattedMessage

TSX
1import { FormattedMessage } from 'react-intl';
2
3function Header() {
4  return (
5    <header>
6      <h1>
7        <FormattedMessage id="app.greeting" />
8      </h1>
9      <nav>
10        <a href="/"><FormattedMessage id="app.nav.home" /></a>
11        <a href="/about"><FormattedMessage id="app.nav.about" /></a>
12      </nav>
13    </header>
14  );
15}

Le Hook useIntl

Pour un accès programmatique au formatage :

TSX
1import { useIntl } from 'react-intl';
2
3function Form() {
4  const intl = useIntl();
5
6  const handleSubmit = () => {
7    const confirmMessage = intl.formatMessage({ id: 'app.confirm' });
8    if (confirm(confirmMessage)) {
9      // Soumettre formulaire
10    }
11  };
12
13  return (
14    <form onSubmit={handleSubmit}>
15      <button type="submit">
16        {intl.formatMessage({ id: 'app.buttons.submit' })}
17      </button>
18    </form>
19  );
20}

Méthodes du Hook

MéthodeObjectifExemple
formatMessageTraduire messageintl.formatMessage({ id: 'key' })
formatDateFormater dateintl.formatDate(new Date())
formatTimeFormater heureintl.formatTime(new Date())
formatNumberFormater nombreintl.formatNumber(1234.56)
formatRelativeTimeTemps relatifintl.formatRelativeTime(-1, 'day')

Format de Message ICU

ICU (International Components for Unicode) est la norme de l'industrie pour les messages complexes.

Variables (Arguments)

JSON
1{
2  "greeting": "Bonjour, {name} !",
3  "cartInfo": "Vous avez {count} articles valant {total}"
4}
TSX
1<FormattedMessage
2  id="greeting"
3  values={{ name: user.name }}
4/>
5
6<FormattedMessage
7  id="cartInfo"
8  values={{ count: 5, total: '99,99 €' }}
9/>

Pluralisation

ICU gère les règles plurielles complexes pour toutes les langues :

JSON
{
  "items": "{count, plural, =0 {Aucun article} one {# article} other {# articles}}"
}
TSX
1<FormattedMessage id="items" values={{ count: 0 }} />
2// "Aucun article"
3
4<FormattedMessage id="items" values={{ count: 1 }} />
5// "1 article"
6
7<FormattedMessage id="items" values={{ count: 5 }} />
8// "5 articles"

Formes plurielles complexes (Russe) :

JSON
{
  "items": "{count, plural, one {# товар} few {# товара} many {# товаров} other {# товаров}}"
}

Select (Genre, Choix)

JSON
{
  "pronoun": "{gender, select, male {Il a} female {Elle a} other {Ils ont}} aimé votre article"
}
TSX
1<FormattedMessage
2  id="pronoun"
3  values={{ gender: 'female' }}
4/>
5// "Elle a aimé votre article"

Pluriel Imbriqué + Select

JSON
{
  "invites": "{gender, select, male {{count, plural, one {Il a invité # personne} other {Il a invité # personnes}}} female {{count, plural, one {Elle a invité # personne} other {Elle a invité # personnes}}} other {{count, plural, one {Ils ont invité # personne} other {Ils ont invité # personnes}}}}"
}

Texte Riche (Composants HTML)

JSON
1{
2  "terms": "En vous inscrivant, vous acceptez nos <link>Conditions</link>",
3  "welcome": "Bienvenue <bold>{name}</bold> sur notre plateforme !"
4}
TSX
1<FormattedMessage
2  id="terms"
3  values={{
4    link: (chunks) => <a href="/terms">{chunks}</a>
5  }}
6/>
7
8<FormattedMessage
9  id="welcome"
10  values={{
11    name: user.name,
12    bold: (chunks) => <strong>{chunks}</strong>
13  }}
14/>

Formateurs Intégrés

Formatage de Date

TSX
1import { FormattedDate } from 'react-intl';
2
3<FormattedDate
4  value={new Date()}
5  year="numeric"
6  month="long"
7  day="2-digit"
8/>
9// "17 janvier 2026" (fr)

Formatage d'Heure

TSX
1import { FormattedTime } from 'react-intl';
2
3<FormattedTime
4  value={new Date()}
5  hour="numeric"
6  minute="numeric"
7  timeZoneName="short"
8/>
9// "14:30 EST" (fr)

Formatage de Nombre

TSX
1import { FormattedNumber } from 'react-intl';
2
3// Nombre simple
4<FormattedNumber value={1234567.89} />
5// "1 234 567,89" (fr)
6
7// Devise
8<FormattedNumber
9  value={99.99}
10  style="currency"
11  currency="EUR"
12/>
13// "99,99 €" (fr)
14
15// Pourcentage
16<FormattedNumber value={0.25} style="percent" />
17// "25 %"

Temps Relatif

TSX
1import { FormattedRelativeTime } from 'react-intl';
2
3<FormattedRelativeTime value={-1} unit="day" />
4// "hier"
5
6<FormattedRelativeTime value={3} unit="hour" />
7// "dans 3 heures"

Intégration TypeScript

Définir les Types de Message

TypeScript
1// src/types/intl.d.ts
2import fr from '../lang/fr.json';
3
4type Messages = typeof fr;
5
6declare global {
7  namespace FormatjsIntl {
8    interface Message {
9      ids: keyof Messages;
10    }
11  }
12}

Maintenant TypeScript autocomplète et valide les IDs de message :

TSX
<FormattedMessage id="app.greeting" />  // ✅ Valide
<FormattedMessage id="invalid.key" />   // ❌ Erreur TypeScript

defineMessages pour l'Extraction

TSX
1import { defineMessages, useIntl } from 'react-intl';
2
3const messages = defineMessages({
4  title: {
5    id: 'app.title',
6    defaultMessage: 'My Application',
7    description: 'Main application title',
8  },
9  greeting: {
10    id: 'app.greeting',
11    defaultMessage: 'Hello, {name}!',
12    description: 'User greeting message',
13  },
14});

Extraction de Message

Extraire avec FormatJS CLI

Terminal
# Extraire les messages des fichiers sources
npx formatjs extract 'src/**/*.ts*' --out-file lang/en.json --id-interpolation-pattern '[sha512:contenthash:base64:6]'

Compiler pour la Production

Terminal
# Compiler en AST pour une meilleure performance
npx formatjs compile lang/en.json --out-file lang/compiled/en.json
npx formatjs compile lang/fr.json --out-file lang/compiled/fr.json

Utiliser les messages compilés :

TSX
1import compiledMessages from './lang/compiled/fr.json';
2
3<IntlProvider
4  locale="fr"
5  messages={compiledMessages}
6/>

Les messages compilés sont pré-analysés, améliorant la performance d'exécution de 30-50%.

Changement de Langue

TSX
1import { useState, useCallback } from 'react';
2import { IntlProvider } from 'react-intl';
3
4const SUPPORTED_LOCALES = ['en', 'fr'] as const;
5type Locale = typeof SUPPORTED_LOCALES[number];
6
7function App() {
8  const [locale, setLocale] = useState<Locale>('fr');
9  const [messages, setMessages] = useState(frMessages);
10
11  const handleLocaleChange = useCallback(async (newLocale: Locale) => {
12    // Importer dynamiquement les traductions
13    const newMessages = await import(`./lang/${newLocale}.json`);
14    setMessages(newMessages.default);
15    setLocale(newLocale);
16
17    // Persister la préférence
18    localStorage.setItem('locale', newLocale);
19    document.documentElement.lang = newLocale;
20  }, []);
21
22  // ... Rendu
23}

Rendu Côté Serveur

Intégration Next.js

TSX
1// app/[locale]/layout.tsx
2import { IntlProvider } from 'react-intl';
3
4async function loadMessages(locale: string) {
5  return (await import(`../../lang/${locale}.json`)).default;
6}
7
8export default async function LocaleLayout({
9  children,
10  params: { locale },
11}: {
12  children: React.ReactNode;
13  params: { locale: string };
14}) {
15  const messages = await loadMessages(locale);
16
17  return (
18    <IntlProvider locale={locale} messages={messages}>
19      {children}
20    </IntlProvider>
21  );
22}

Note : Pour Next.js App Router, considérez next-intl qui fournit une meilleure intégration RSC.

Tester

Configuration de Test

TSX
1// test/test-utils.tsx
2import { render } from '@testing-library/react';
3import { IntlProvider } from 'react-intl';
4
5const messages = {
6  'app.greeting': 'Hello, {name}!',
7};
8
9function Wrapper({ children }: { children: React.ReactNode }) {
10  return (
11    <IntlProvider locale="en" messages={messages}>
12      {children}
13    </IntlProvider>
14  );
15}
16
17export function renderWithIntl(ui: React.ReactElement) {
18  return render(ui, { wrapper: Wrapper });
19}

Meilleures Pratiques de Production

1. Convention d'ID de Message

JSON
1{
2  "namespace.componsant.element": "Valeur",
3  "auth.login.title": "Se connecter"
4}

2. Toujours Fournir des Messages par Défaut

TSX
1<FormattedMessage
2  id="app.greeting"
3  defaultMessage="Welcome to our app"
4/>

3. Utiliser des Messages Compilés en Production

Les messages AST compilés sautent l'analyse d'exécution, améliorant la performance.

Intégration avec IntlPull

IntlPull fonctionne parfaitement avec react-intl et le format ICU :

Flux de Travail CLI

Terminal
1# Extraire les messages
2npx formatjs extract 'src/**/*.ts*' --out-file lang/extracted.json
3
4# Télécharger sur IntlPull
5npx @intlpullhq/cli upload --file lang/extracted.json --format icu
6
7# Traduire avec IA
8npx @intlpullhq/cli translate --target fr
9
10# Télécharger les traductions
11npx @intlpullhq/cli download --output lang/ --format json

Avantages

  • Support ICU : IntlPull préserve parfaitement la syntaxe ICU
  • Traduction IA : GPT-4 et Claude comprennent les espaces réservés ICU
  • Validation : Attrape les erreurs de syntaxe ICU avant le déploiement

Foire Aux Questions

Qu'est-ce que react-intl ?

react-intl est la liaison React pour FormatJS, fournissant l'internationalisation avec le support du Format de Message ICU. Il offre des composants comme FormattedMessage, FormattedDate et FormattedNumber, plus le hook useIntl. C'est le choix de référence pour les projets nécessitant une conformité ICU stricte.

Quelle est la différence entre react-intl et react-i18next ?

react-intl utilise le Format de Message ICU avec une syntaxe stricte pour les pluriels et sélections. react-i18next utilise des clés JSON plus simples avec des pluriels basés sur des suffixes. react-intl a des formateurs intégrés pour dates/nombres ; react-i18next nécessite des plugins. Choisissez react-intl pour la conformité ICU ; choisissez react-i18next pour une syntaxe plus simple.

Comment j'utilise FormattedMessage avec des variables ?

Utilisez la syntaxe d'accolades dans les messages ICU : "greeting": "Bonjour, {name} !". Puis passez les valeurs : <FormattedMessage id="greeting" values={{ name: 'Jean' }} />.

Comment fonctionne la pluralisation dans react-intl ?

Utilisez la syntaxe plurielle ICU : "{count, plural, one {# article} other {# articles}}". ICU supporte les catégories zero, one, two, few, many, other.

Comment formater les dates et nombres dans react-intl ?

Utilisez les composants formateurs intégrés : <FormattedDate value={date} dateStyle="long" />, <FormattedNumber value={1234.56} style="currency" currency="EUR" />. Le formatage est automatiquement conscient de la locale.

Comment j'extrais les messages du code ?

Utilisez FormatJS CLI : npx formatjs extract 'src/**/*.ts*' --out-file lang/en.json. Définissez les messages avec defineMessages() pour une meilleure extraction.

Devrais-je compiler les messages pour la production ?

Oui, compilez les messages pour 30-50% de meilleure performance. Exécutez npx formatjs compile. Les messages compilés sont des ASTs pré-analysés, sautant l'analyse d'exécution.

Résumé

react-intl fournit une internationalisation robuste avec le Format de Message ICU :

AspectDétails
Installationnpm install react-intl
Provider<IntlProvider locale messages>
Composant<FormattedMessage id values />
HookuseIntl().formatMessage()
Format de MessageICU (standard)
FormateursDate, nombre, devise intégrés

Meilleur pour : Équipes nécessitant une conformité ICU, des formateurs intégrés, ou une intégration avec des outils TAO qui utilisent ICU.

Pour des besoins plus simples, considérez react-i18next.

Prêt à gérer les traductions react-intl ? Commencez gratuitement avec IntlPull — support ICU complet avec traduction IA.

Tags
react-intl
formatjs
react
i18n
internationalization
icu
2026
IntlPull Team
IntlPull Team
Engineering

Building tools to help teams ship products globally. Follow us for more insights on localization and i18n.