Soluling home   Document home

React Localization and Internationalization

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.

Configure the application to use React Intl

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')
); 

Mark the strings you want to localize

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.

Extract the strings from the source code

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.

Create a Soluling project

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.

Localized options

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.

Select languages

We added Finnish and German as target languages and English as the original language. Complete the wizard by clicking Finish. A new project appears.

New project

Next, translate the strings.

Translated project

Finally, click Build All to build the localized resource files in the src/translations directory.

Configure the application to use the localized resource files

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.

Samples

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:

original The original English only Tic-Tac-Toe application
react-int A localized Tic-Tac-Toe application that uses React Intl.
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.