React Intl
React Intl is a mature and widely-used library for internationalizing React applications. It provides a comprehensive set of components and an API for formatting dates, numbers, and strings, including complex pluralization and translation handling, leveraging JavaScript's built-in `Intl` API. Currently at version 10.1.2, it is part of the broader FormatJS ecosystem, which also includes tools for message extraction and compilation. The library maintains an active development pace, with regular patch and minor releases, and significant major version updates to keep pace with React and JavaScript ecosystem changes. Its key differentiators include a component-based approach for common UI elements, a hook-based API for imperative formatting, and robust support for ICU MessageFormat syntax, making it a powerful choice for globalized React apps.
Common errors
-
Error: [React Intl] IntlProvider was not found in the React context.
cause Attempting to use `FormattedMessage`, `useIntl`, or other `react-intl` components/hooks outside of an `IntlProvider`'s context.fixEnsure that your entire application or the relevant component tree is wrapped within an `IntlProvider` component, providing the `locale` and `messages` props. -
TypeError: (0 , react_intl__WEBPACK_IMPORTED_MODULE_2__.useIntl) is not a function
cause This typically occurs in older React environments (pre-16.8) where hooks are not supported, or if there's a module resolution issue where an older `react-intl` version without hooks is being loaded, or incorrect Babel/Webpack configuration.fixVerify that your `react` dependency is at least `16.8.0`. Check your module bundler configuration to ensure `react-intl` is correctly resolved and that you're using a compatible version. Update `react-intl` to a version that supports hooks. -
Invariant Violation: [React Intl] The 'locale' prop must be a string.
cause The `locale` prop passed to `IntlProvider` is not a string, or is `undefined` (e.g., due to a variable not being correctly initialized).fixEnsure the `locale` prop passed to `IntlProvider` is always a valid BCP 47 language tag string, such as 'en-US' or 'fr-FR'. Consider a fallback mechanism for determining the user's locale. -
ReferenceError: Intl is not defined
cause The JavaScript runtime environment (e.g., older browsers, specific Node.js builds, or React Native environments without `Intl` support) lacks the native `Intl` object or required `Intl` APIs.fixInclude polyfills for the `Intl` object and specific `Intl` APIs (`Intl.PluralRules`, `Intl.RelativeTimeFormat`, etc.) as needed for your target environments. For Node.js, ensure version 16+ is used. -
Warning: Missing locale data for locale: "undefined". Using default locale: "en" as fallback.
cause This warning indicates that `react-intl` cannot find the necessary locale data for the requested locale, often because the data hasn't been imported or the locale string is incorrect/missing, causing it to fall back to English.fixEnsure you are explicitly importing locale data for all supported languages using `@formatjs/intl-*` packages (e.g., `import '@formatjs/intl-pluralrules/locale-data/fr';`) and that your `IntlProvider` correctly receives the `locale` prop.
Warnings
- breaking React Intl v10.x primarily targets React 19. Ensure your project's React and `@types/react` dependencies are updated accordingly. Older React versions might encounter compatibility issues, especially with internal key handling for elements in arrays.
- breaking Starting with React Intl v7, support for Node.js versions older than 16 was dropped. Ensure your development and deployment environments run Node.js 16 or later to leverage full internationalization support natively.
- breaking Earlier versions of React Intl (e.g., v8.x) addressed key warnings related to React 19's stricter key handling when using `React.cloneElement` internally. If upgrading from older versions, be aware of changes to how rich text elements are wrapped (now often with `React.Fragment`).
- gotcha By default, `react-intl` bundles with only basic English locale data. To support other languages, you must explicitly import and add the necessary locale data, particularly for features like `Intl.PluralRules` or `Intl.RelativeTimeFormat`.
- gotcha All `react-intl` components and hooks must be rendered within an `IntlProvider`. Failure to do so will result in an error indicating that `IntlProvider` was not found in the React context.
- gotcha React Intl expects message IDs to be simple strings (e.g., `homepage.header.greeting`). Using deeply nested JavaScript objects for message IDs within the `messages` prop can lead to unexpected behavior or difficulties with message extraction tools.
Install
-
npm install react-intl -
yarn add react-intl -
pnpm add react-intl
Imports
- IntlProvider
const IntlProvider = require('react-intl').IntlProvider;import { IntlProvider } from 'react-intl'; - FormattedMessage
import FormattedMessage from 'react-intl';
import { FormattedMessage } from 'react-intl'; - useIntl
import { useIntl } from 'react-intl/hooks'; /* deprecated path */import { useIntl } from 'react-intl'; - defineMessages
import defineMessages from 'react-intl';
import { defineMessages } from 'react-intl';
Quickstart
import React from 'react';
import { IntlProvider, FormattedMessage, useIntl } from 'react-intl';
// Define messages for a specific locale
const messagesInFrench = {
greeting: 'Bonjour {name}, bienvenue sur notre site !',
welcome_page_title: 'Page d\'accueil',
current_date: 'Aujourd\'hui, {ts, date, ::full}',
unread_notifications: '{count, plural, one {# notification non lue} other {# notifications non lues}}',
product_price: 'Prix : {price, number, currency}',
};
// Example functional component using FormattedMessage and useIntl hook
const HomePage = () => {
const intl = useIntl();
const userName = 'Jean-Luc';
const notificationCount = 3;
const productPrice = 42.50;
return (
<div>
<h1>{intl.formatMessage({ id: 'welcome_page_title' })}</h1>
<p>
<FormattedMessage
id="greeting"
values={{ name: <b>{userName}</b> }}
/>
</p>
<p>
<FormattedMessage
id="current_date"
values={{ ts: new Date() }}
/>
</p>
<p>
<FormattedMessage
id="unread_notifications"
values={{ count: notificationCount }}
/>
</p>
<p>
<FormattedMessage
id="product_price"
values={{ price: productPrice, currency: 'EUR' }}
/>
</p>
</div>
);
};
// Root component to provide the IntlProvider context
const App = () => (
<IntlProvider locale="fr-FR" messages={messagesInFrench}>
<HomePage />
</IntlProvider>
);
export default App;