How To Localize React Application Using `react-intl`
In this tutorial we'll localize React application from start to finish using react-intl made by Yahoo.
We'll use create-react-app to generate a new application and then we'll go through the whole set of steps needed to localize it using react-intl.
In this tutorial I assume that you have modern
nodeversion installed.
1. Create New Application
First let's generate our boilerplate, run create-react-app:
npx create-react-app react-intl-example
I'm using npx here, but you can just run create-react-app if you have it installed globally.
2. Install react-intl
After create-react-app finishes installation - cd to your app folder and install react-intl.
cd react-intl-example
yarn add react-intl
3. Wrap App Into IntlProvider
Go to index.js, import IntlProvider from react-intl, and wrap <App/> element.
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>
<App />
</IntlProvider>,
document.getElementById("root")
);
serviceWorker.unregister();
4. Wrap Texts Into FormatMessage Components
Open App.js, import FormattedMessage and wrap each text into FormattedMessage component. You need to provide id and defaultMessage for each element:
import React, { Component } from "react";
import { FormattedMessage} from 'react-intl'
import logo from "./logo.svg";
import "./App.css";
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
<FormattedMessage
id="add.edit"
defaultMessage="Edit {code} and save to reload."
values={{
code: <code>src/App.js</code>
}}
/>
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
<FormattedMessage id="app.learn" defaultMessage="Learn React" />
</a>
</header>
</div>
);
}
}
export default App;
Note that we used
valuesfield to pass the named placeholdercode, that contained some markup (the<code>tags).
5. Extract Messages
Sometimes this step is performed manually, just by adding id's and with text values to the translation files.
It can, and I think it should, be automated. We'll use react-intl-cra. It is a package that is pre-configured to work with create-react-app generated applications. Install this script:
yarn add react-intl-cra
Add it to scripts section in package.json:
"extract:messages": "react-intl-cra 'src/**/*.{js,jsx}' -o 'src/i18n/messages/messages.json'",
Run the script:
yarn extract:messages
It will generate a new file src/i18n/messages/messages.json. This file will contain all the found texts from your source code.
6. Generate The Locales
Now we'll need another package react-intl-translations-manager to generate the locale files from the messages file.
Install the package:
yarn add react-intl-translations-manager
This package only has programmatic interface so you'll need to create the script file. Create translationRunner.js file with the following contents:
// translationRunner.js
const manageTranslations = require('react-intl-translations-manager').default;
manageTranslations({
messagesDirectory: 'src/i18n/messages/',
translationsDirectory: 'src/i18n/locales/',
languages: ['en','sv', 'es'] // any language you need
});
And add the command to run this script to your package.json:
{
"scripts": {
"manage:translations": "node ./translationRunner.js"
}
}
Run the script:
yarn manage:translations
It will generate locales ready to be used in the src/translations/locales folder.
7. Translate The Locales
Now you can translate your locales manually, or use one of the translation services to do that. Here are a few examples of Translation Management Systems:
You have to upload your translations there, translate the messages and then download translated locales.
8. Load Translation Through Intl Provider
Create index.js in src/translations/locales and export all the translations from it:
import en from "./en.json";
import es from "./es.json";
import sv from "./sv.json";
export default { en, es, sv }
Add locale data to react-intl:
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { IntlProvider, addLocaleData} from "react-intl";
import esLocaleData from "react-intl/locale-data/es";
import svLocaleData from "react-intl/locale-data/sv";
import translations from './i18n/locales'
addLocaleData(esLocaleData);
addLocaleData(svLocaleData);
const locale = window.location.search.replace("?locale=","") || "en"
const messages = translations[locale];
ReactDOM.render(
<IntlProvider locale={locale} messages={messages}>
<App />
</IntlProvider>,
document.getElementById("root")
);
serviceWorker.unregister();
9. Run Your Application
Now you can run your app, try adding different locale codes to your url.
Here is the code for the app in this tutorial.