React Localization and Internationalization |
React (Wikipedia) is a very popular JavaScript framework to build browser applications. There is no built-in localization support to React, but you have to use a 3rd party implementation. The most common add-ons are
No matter which one of these 3rd party add-ons you use, Soluling localization tool and service support React. In this tutorial, we are going to internationalize React's Into to React sample. The sample implements a tic-tac-toe game. This tutorial uses the Rect Intl add-on. If you use LinguiJS or i18next, the process is similar, but you have to adapt it a bit.
The end of the document contains links to get the full source code of the samples. After reading this document, we recommend reading a tutorial about how to use Soluling.
Install the react-intl via npm:
npm install react-intl --save
Initially, the application configuration looks like this.
ReactDOM.render( <Game />, document.getElementById('root') );
Create an I18N context. Get the locale from the navigator's locale and add IntlProvider.
import { IntlProvider } from 'react-intl';
...
let language = navigator.language || 'en';
ReactDOM.render(
<IntlProvider locale={language}>
<Game />,
</IntlProvider>,
document.getElementById('root')
);
The next step is to mark all the strings that you want to localize. Import FormatMessage component and injectIntl function.
import { FormattedMessage, IntlProvider, injectIntl } from 'react-intl';
If you have a JSX/HTML string, that you want to localize use FormattedMessage.
<h1>Tic-Tac-Toe Game</h1>
Change it to
<h1><FormattedMessage id="Tic-Tac-Toe Game" /></h1>
FormattedMessage can have four attributes. They are:
Attribute | Required | Description |
---|---|---|
id |
Always | Id of the string. If defaultMessage attribute is not present, then this is also the value of the string. |
defaultMessage |
Depends on the value | The value of the string. If not present, then the id is used as a value. |
description |
Optional | Optional comment. |
values |
If the value is a pattern | Parameters used in the pattern string value. |
If the string is a static text, then you only have to specify the id attribute. That value is used both as an id and value.
If the string is a pattern (i.e., contains placeholders), Then you have to specify id, defaultMessage, and values attributes. For example:
<h1><FormattedMessage id="name" defaultMessage="Hello, {name]", values={{name: 'John'}}/></h1>
Even the description is optional, it is a good practice to use it if the string needs extra description or the string is a pattern. For example, in the case of a pattern, you should describe each parameter.
<h1><FormattedMessage id="name" defaultMessage="Hello, {name]", description="name: Name of the user" values={{name: 'John'}}/></h1>
If you want to localize a string in JavaScript code, then you have to first inject the intl
property.
Game = injectIntl(Game);
After that you can use the intl
property.
render() { const intl = this.props.intl; ... intl.formatMessage({id: 'Go to game start'}); }
If the string contains patterns, use the following syntax.
intl.formatMessage({id: 'Go to move # {move}', defaultMessage: 'Go to move # {move}'}, { move: move});
Note that the parameter values are passed as a second parameter.
Now when you have marked all the strings, it is time to extract the strings from the source code into a resource file. Start by installing the extract tool.
npm -g i @formatjs/cli
If you use JavaScript, add the following line to your package.json.
"scripts": { ... "extract": "formatjs extract --out-file src/translations/en.json src/**/*.{js,jsx}" },
If you use Typescript, add the following line to your package.json.
"scripts": { ... "extract": "formatjs extract --out-file src/translations/en.json --ignore=**/*.d.ts src/**/*.{ts,tsx}" },
Finally, run the following command.
npm run extract
The command scans your source code, extract the template and source code strings, and finally writes them to src/translations/en.json
file. This file is your original resource file. Run the above command each time you have modified any strings in your source code.
Now it is time to create a Soluling project for our internationalized application. Start Soluling. Drag and drop src/transltions/en.json
file into Soluling or click New from File or Files and browse the en.json
file. The project wizard shows the Select File Type dialog.
Select React-Intl resource file and click OK. Select Languages page appears. Add the languages you want to support and also select the original language.
We added Finnish and German as target languages and English as the original language. Complete the wizard by clicking Finish. A new project appears.
Next, translate the strings.
Finally, click Build All to build the localized resource files in the src/translations directory.
The file that was extracted uses a different format than the file you should use in the application on runtime. Both formats use JSON, but the runtime format uses a flat structure and does not contain comments. Fortunately, Soluling does the conversion for you. Soluling scans the extracted file format (or the manually created runtime format) but always writes the runtime file format. Follow these instructions to use the localized resource files in your application.
First, you have to import each resource file.
import messages_de from "./translations/de.json"; import messages_fi from "./translations/fi.json"; import messages_ja from "./translations/ja.json";
Then you create an object that combines all these resources and pass it to IntlProvider
.
const messages = { 'de': messages_de, 'fi': messages_fi, 'ja': messages_ja }; let language = navigator.language || 'en'; language = language.split(/[-_]/)[0]; // language without region code ReactDOM.render(
<IntlProvider locale={language} messages={messages[language]}>
<Game />,
</IntlProvider>,
document.getElementById('root')
);
That's it. Now your React application is multilingual. Set your browser language to a language you used and run the application.
GitHub and <data-dir>\Samples\React contains following React samples:
GitHub/Directory | Description | Notes | ||||
---|---|---|---|---|---|---|
tic | React's Tic-tac-toe tutorial sample. Contains following projects:
|
Try this first! | ||||
sport | Localized React application that consumes a multilingual Sport API. Uses React Intl. | Learn more about the application from here. | ||||
sport-ts | Localized typescript React application that consumes a multilingual Sport API. Uses React Intl. | Learn more about the application from here. | ||||
i18next\sample | A simple React application that uses i18next. |
|||||
Intl\sample | A simple React application that uses React Intl. |
|||||
Lingui\hello | A simple React application that uses LinguiJS. |