How to Internationalize (i18n) React 16+ App with react-intl Package

Last updated on by Digamber
In this tutorial, we will learn how to Internationalize a React application using a react-intl package.

Internationalization

Internationalization is the design and development of a product, application or document content that enables easy localization for target audiences that vary in culture, region, or language.
www.w3.org

Nowadays, the world has become smaller, thanks to globalization. Do you want to know how this has become possible? I believe technology played the vital role in bringing the world closer. It’s not just the word. It contains the entire world in it.

Thanks to technology, it is advancing businesses and helping them to spread across the globe, more applications are being developed for the global community.

Be it a language or dialect, your application must match the requirements of a global audience. Whether you want it or not, but if you are the product owner, then you must develop your product considering the needs of a locale audience.

This step by step tutorial will guide you on how to build a multilingual React app using the react-intl package. Usually, React does not come pre-packed with internationalization (i18n) support, but we can make it possible with the react-intl plugin.

Setting up React Project

Let’s start by setting up a brand new React app using create react app.

npx create-react-app react-i18n-example

Get inside the project folder:

cd react-intl-example

Start the app in the browser:

npm start

Adding react-intl to React 16+ App

The react-intl offers i18n support and allows you to translate the content for various application elements such as numbers formats, dates, text paragraphs, tables, headers and buttons.

Install react-intl plugin to localize React application.

npm install react-intl

It helps in internationalizing React app and offers the following features:

  • Built on standards.
  • Show numbers with separators.
  • Show dates and times correctly.
  • Show dates relative to “now”.
  • Pluralize labels in strings.
  • Offers150+ language support.
  • Runs in the browser and Node.js.

Wrap React App with IntlProvider Component

Enabling internationalization is easy we have to import the IntlProvider, then wrap React app with <IntlProvider> component:

Open src/Index.js file and place the following code in it:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

import {IntlProvider} from "react-intl";

ReactDOM.render(
    <IntlProvider locale='en'>
        <App/>
    </IntlProvider>,
    document.getElementById('root')
);

serviceWorker.unregister();

Wrap Text with FormattedMessage and FormattedHtmlMessage

Next, we will wrapt the content of our React app using FormattedMessage and FormattedHtmlMessage components.

Open src/App.js file and import FormattedMessage and FormattedHtmlMessage components.

import React from "react";
import {FormattedMessage, FormattedHTMLMessage} from 'react-intl';

function App() {
  return (
    <div className="App">
      <p>
        <FormattedHTMLMessage
          id="app.text"
          defaultMessage="Hello, welcome {user}"
          description="Welcome message"
          values={{ user: "John Doe" }}/>
      </p>
      <a href="https://www.positronx.io" target="_blank" rel="noopener noreferrer">
        <FormattedMessage
          id="app.link"
          defaultMessage="Go to link"
          description="Check website"/>
      </a>
    </div>
  );
}

export default App;

Replace the <p> HTML tag with FormattedHTMLMessage and <a> HTML tag with FormattedMessage components. Add default message the user will see it.

Note that we have added the values with curly braces, this contains some text values.

We wrapped {user} value the text with a FormattedMessage or FormattedHTMLMessage components to translate the text and link.

Create Translations Message with Language JSON Files:

Create src/translations folder in your project and create files for the locale you want to add the support in your React app.

We are going to create translation files for English and Dutch locales, and then we will add the locale data in both locale en and locale nl files.

Here is the content we placed in our locale files.

src/translations/en.json:

{
    "app.text": "Hallo, welcome {user}",
    "app.link": "Go to link"
}

src/translations/nl.json:

{
    "app.text": "Hallo, welkom {user}",
    "app.link": "Ga naar link"
}

We have placed the locale files at the right place, now IntlProvider will show the locale data as per the language used by the browser.

Replace the final code in the src/index.js file:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

import {IntlProvider} from "react-intl";
import locale_en from "./translations/en.json";
import locale_nl from "./translations/nl.json";

const data = {
  'nl': locale_nl,
  'en': locale_en
};

const language = navigator.language.split(/[-_]/)[0];

ReactDOM.render(
  <IntlProvider locale={language} messages={data[language]}>
      <App/>
  </IntlProvider>,
  document.getElementById('root')
);

serviceWorker.unregister();

We need to change the browser language via settings to see how the preferred language is working in our React application.

Note that if you set other languages than “en” or “nl”, then the react-intl will show the defaultText and translation messages will be seen as undefined.

Extract Messages with babel-plugin-react-intl

We can perform this task using the babel-plugin-react-intl plugins. Run the following command to install the plugins.

npm install @babel/core @babel/cli babel-plugin-react-intl --save-dev

Next, create a .babelrc file at the root of your project folder. The babel-plugin-react-intl will keep, all the extracted message IDs in the build/message folder with associated json files.

Add the following code in it:

{
    "presets": ["react-app"],
    "plugins": [
        [ "react-intl", {
            "messagesDir": "./build/messages",
            "extractSourceLocation": true
        }]
    ]
}

Now, go to the package.json file and add either of the code inside the scripts array based on your system.

"scripts": {
    "extract-messages": "set NODE_ENV=production&& babel ./src >NUL",              (Windows)
    "extract-messages": "NODE_ENV=production babel ./src  --out-file /dev/null"    (Linux/Mac)
}

You can use the following command to extract the messages via a babel plugin.

npm run extract-messages

Now, run your React application and try checking the different locale.

You can get the complete code of this project on this GitHub repo.

Conclusion

Finally, we have finished the React Internationalization (i18n) tutorial. In this tutorial, we learned how to translate React 16+ App using the react-intl package.