Aller au contenu principal

Vue d'ensemble

Traduction Bêta Non Officielle

Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →

npm Version

Bienvenue dans la documentation de React Intl ! Vous trouverez ici toute la documentation de React Intl. N'hésitez pas à ouvrir une pull request pour contribuer à l'améliorer.

Prérequis d'exécution

Nous prenons en charge IE11 et les 2 dernières versions de Edge, Chrome, Firefox et Safari.

React Intl repose sur ces API Intl :

Pour supporter les navigateurs plus anciens, nous recommandons les étapes suivantes :

  1. Pour les navigateurs sans Intl, incluez ce polyfill dans votre build.

  2. Polyfill Intl.NumberFormat avec @formatjs/intl-numberformat.

  3. Polyfill Intl.DateTimeFormat avec @formatjs/intl-datetimeformat

  4. Pour les navigateurs sans Intl.PluralRules (ex: IE11 et Safari 12-), incluez ce polyfill dans votre build.

  5. Pour les navigateurs sans Intl.RelativeTimeFormat (ex: IE11, Edge, Safari 12-), incluez ce polyfill avec les données CLDR spécifiques à chaque langue supportée.

  6. Si vous avez besoin de Intl.DisplayNames, incluez ce polyfill avec les données CLDR spécifiques à chaque langue supportée.

Node.js

full-icu

À partir de Node.js 13.0.0, full-icu est pris en charge par défaut.

Si vous utilisez React Intl dans une version antérieure de Node.js, votre binaire node doit soit :

OU

Si votre version de node ne dispose pas de l'une des API Intl ci-dessus, vous devrez les polyfiller en conséquence.

React Native

Si vous utilisez react-intl dans React Native, assurez-vous que votre runtime dispose d'une prise en charge Intl intégrée (similaire à la variante internationale de JSC). Consultez ces problèmes pour plus de détails :

React Native sur iOS

Si vous ne pouvez pas utiliser la variante Intl de JSC (ex: sur iOS), suivez les instructions dans Prérequis d'exécution pour polyfiller ces API.

Le package react-intl

Installez le package npm react-intl via npm :

npm i -S react-intl

Le package npm react-intl distribue les modules suivants (liens depuis unpkg) :

  • CommonJS : dépendances non regroupées, "main" dans package.json, avertissements en dev.

  • ES6 : dépendances non regroupées, "module" dans package.json, avertissements en dev.

Bundlers de modules

React Intl fonctionne avec les bundlers de modules comme Browserify, Webpack ou Rollup pour créer des bundles navigateur :

  • Le champ "browser" dans package.json garantit que seules les données locales anglaises de base sont incluses dans le bundle. Ainsi, le module "main" charge toutes les données locales en Node, mais les ignore dans les bundles navigateur.

  • Une version ES6 de React Intl est fournie via "jsnext:main" et "module" dans package.json pour une utilisation avec Rollup.

  • Les avertissements en mode développement sont conditionnés par process.env.NODE_ENV !== 'production', ce qui vous permet de spécifier NODE_ENV lors du bundling et de la minification pour supprimer ces blocs de code.

Le module React Intl

Que vous utilisiez la version ES6, CommonJS ou UMD de React Intl, elles exposent toutes les mêmes exports nommés :

react

Lorsque vous utilisez la version UMD de React Intl sans système de modules, elle s'attendra à ce que react existe dans la variable globale : React, et placera les exports nommés ci-dessus dans la variable globale : ReactIntl.

Création d'un contexte I18n

Maintenant que React Intl et ses données de locale sont chargés, un contexte i18n peut être créé pour votre application React.

React Intl utilise le modèle de provider pour délimiter un contexte i18n à un arbre de composants. Cette approche permet de fournir au niveau racine des configurations comme la locale courante et les messages traduits, rendus disponibles pour les composants <Formatted*>. C'est le même concept que les frameworks Flux comme Redux utilisent pour exposer un store dans un arbre de composants.

Toutes les applications utilisant React Intl doivent utiliser le composant <IntlProvider>.

L'utilisation la plus courante consiste à encapsuler votre composant racine React avec <IntlProvider> en le configurant avec la locale actuelle de l'utilisateur et les chaînes/messages traduits correspondants :

ReactDOM.render(
<IntlProvider locale={usersLocale} messages={translationsForUsersLocale}>
<App />
</IntlProvider>,
document.getElementById('container')
)

Voir : la documentation de <IntlProvider> pour plus de détails.

Formatage des données

React Intl offre deux méthodes pour formater les données : via des composants React et son API. Les composants fournissent une manière idiomatique-React d'intégrer l'internationalisation dans une application React, et les composants <Formatted*> présentent des avantages par rapport à l'utilisation directe de l'API impérative. L'API doit être utilisée lorsque votre composant React a besoin de formater des données en une valeur chaîne où un élément React n'est pas adapté ; par exemple, pour un attribut title ou aria, ou pour un effet secondaire dans componentDidMount.

L'API impérative de React Intl est accessible via injectIntl, une fabrique de composant d'ordre supérieur (HOC). Elle encapsulera le composant React passé en paramètre avec un autre composant React qui fournit l'API de formatage impérative au composant encapsulé via ses props. (Cela ressemble au pattern connect-to-stores présent dans de nombreuses implémentations Flux.)

Voici un exemple utilisant <IntlProvider>, les composants <Formatted*>, et l'API impérative pour configurer un contexte i18n et formater des données :

import React from 'react';
import ReactDOM from 'react-dom';
import {IntlProvider, FormattedRelative, useIntl} from 'react-intl';

const MS_IN_DAY = 1e3 * 3600 * 24

const PostDate = ({date}) => {
const intl = useIntl()
return (
<span title={intl.formatDate(date)}>
<FormattedRelativeTime value={(Date.now() - date)/MS_IN_DAY} unit="day"/>
</span>
)
});

const App = ({post}) => (
<div>
<h1>{post.title}</h1>
<p>
<PostDate date={post.date} />
</p>
<div>{post.body}</div>
</div>
);

ReactDOM.render(
<IntlProvider locale={navigator.language}>
<App
post={{
title: 'Hello, World!',
date: new Date(1459913574887),
body: 'Amazing content.',
}}
/>
</IntlProvider>,
document.getElementById('container')
);

En supposant que navigator.language soit "en-us" :

<div>
<h1>Hello, World!</h1>
<p><span title="4/5/2016">yesterday</span></p>
<div>Amazing content.</div>
</div>

Voir : la documentation de l'API et la documentation des composants pour plus de détails.

Build ESM

react-intl et ses bibliothèques sous-jacentes (@formatjs/icu-messageformat-parser, intl-messageformat, @formatjs/intl-relativetimeformat) produisent des artefacts ESM. Cela signifie que vous devez configurer votre chaîne de build pour transpiler ces bibliothèques.

Jest

Ajoutez transformIgnorePatterns pour inclure systématiquement ces bibliothèques, par exemple :

{
transformIgnorePatterns: [
'/node_modules/(?!intl-messageformat|@formatjs/icu-messageformat-parser).+\\.js$',
],
}

webpack

Si vous utilisez babel-loader ou ts-loader, vous pouvez choisir l'une de ces options :

  1. Ajoutez ces bibliothèques dans include :
{
include: [
path.join(__dirname, 'node_modules/react-intl'),
path.join(__dirname, 'node_modules/intl-messageformat'),
path.join(__dirname, 'node_modules/@formatjs/icu-messageformat-parser'),
]
}

OU

  1. Ajoutez ces bibliothèques dans exclude :
exclude: /node_modules\/(?!react-intl|intl-messageformat|@formatjs\/icu-messageformat-parser)/,

Concepts fondamentaux

  • Formateurs (Date, Nombre, Message, Relatif)

  • Provider et Injector

  • API et Composants

  • Descripteur de message

  • Syntaxe des messages

  • Définition des messages par défaut pour l'extraction

  • Formats nommés personnalisés

Exemples d'applications

Plusieurs exemples d'applications exécutables sont disponibles dans ce dépôt Git. Ils constituent un excellent moyen de voir les concepts fondamentaux de React Intl en action dans des applications simplifiées.

Référence API

React Intl propose plusieurs couches d'API sur lesquelles il s'appuie. Lorsque vous utilisez React Intl, vous interagirez avec les built-ins Intl, l'API de React Intl et ses composants React :

Utilisation avec TypeScript

react-intl est écrit en TypeScript, offrant ainsi un support de première classe pour TS.

Pour utiliser react-intl avec TypeScript, assurez-vous que la configuration lib de vos compilerOptions inclut ["esnext.intl", "es2017.intl", "es2018.intl"].

Typage des IDs de messages et des locales

Par défaut, le type de la prop id de <FormattedMessage> et de formatMessage est string. Cependant, vous pouvez définir un type plus restrictif pour bénéficier d'autocomplétion et de vérification d'erreurs. Pour ce faire, remplacez l'espace de noms global suivant par le type union de tous vos IDs de messages. Vous pouvez le faire en incluant ceci dans votre code :

declare global {
namespace FormatjsIntl {
interface Message {
ids: keyof typeof messages
}
}
}

messages est l'objet que vous passeriez normalement à <IntlProvider>, ressemblant par exemple à :

const messages = {
greeting: 'Hello',
planet: 'World',
// ...
}

Vous pouvez également remplacer l'espace de noms global suivant pour utiliser un type personnalisé pour les locales :

declare global {
namespace FormatjsIntl {
interface IntlConfig {
locale: 'en' | 'fr'
}
}
}

Typage des formats personnalisés

Par défaut, le type de la prop format pour <FormattedDate>, <FormattedDateParts>, <FormattedTime> et <FormattedTimeParts> est string. Cela s'applique également à la configuration format de formatDate, formatDateParts, formatTime et formatTimeParts. Cependant, vous pouvez définir un type plus restrictif pour bénéficier de l'autocomplétion et de la vérification d'erreurs. Pour ce faire, remplacez l'espace de noms global suivant par le type union de tous vos noms de formats personnalisés. Vous pouvez le faire en incluant le code suivant quelque part dans votre code :

declare global {
namespace FormatjsIntl {
interface Formats {
date: keyof (typeof customFormats)['date']
time: keyof (typeof customFormats)['time']
}
}
}

customFormats est l'objet que vous passeriez normalement à <IntlProvider>, et qui ressemblerait à quelque chose comme :

const customFormats = {
date: {
short: {
month: 'numeric',
day: 'numeric',
year: '2-digit',
},
},
time: {
short: {
hour: 'numeric',
minute: 'numeric',
},
},
}

Utilisation avancée

Notre guide Utilisation avancée propose des conseils supplémentaires pour les configurations de production dans des environnements où la performance est cruciale.

Outils pris en charge

Extraction de messages

Nous avons développé @formatjs/cli qui vous aide à extraire les messages d'une liste de fichiers. Il utilise babel-plugin-formatjs en coulisses et devrait pouvoir extraire les messages si vous les déclarez avec l'un des mécanismes suivants :

import {defineMessages} from 'react-intl'

defineMessages({
foo: {
id: 'foo',
defaultMessage: 'foo',
description: 'bar',
},
})
import {FormattedMessage} from 'react-intl'
;<FormattedMessage id="foo" defaultMessage="foo" description="bar" />
function Comp(props) {
const {intl} = props
return intl.formatMessage({
// The whole `intl.formatMessage` is required so we can extract
id: 'foo',
defaultMessage: 'foo',
description: 'bar',
})
}

Plugin ESLint

Nous avons également créé eslint-plugin-formatjs qui aide à appliquer des règles spécifiques à vos messages si votre prestataire de traduction impose des restrictions.