FormatJS and React application localization

post header

Start with FormatJS library (originally react-intl)

Today I will show you how localize React application using formatjs.io library (originally yahoo/react-intl). Please notice that this is not the only popular library for React app localization. Second popular library is i18next which supports much more frameworks than FormatJS. If you are interested in i18next integration, you can check our tutorial here.

Create a sample project

I will start with something simple. I will create a new project using create-react-app

yarn create react-app simplelocalize-react-intl-example

Install dependencies

Add react-intl library to your newly created project.

# Using NPM
npm i -S react react-intl

# Using yarn
yarn add react react-intl

Add Language Context

In this project I will use Context to keep translations and option to change language in realtime.

import React from 'react';

const LanguageContext = React.createContext("en");

export default LanguageContext;

Read more about React Context API

react-intl configuration

Let's create main configuration

import React from "react";
import {IntlProvider} from 'react-intl'
import LanguageContext from "./LanguageContext";

class SimpleLocalize extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      messages: undefined,
      language: "en"
    };
  }

  componentDidMount() {
    this.setupLanguageMessages(this.state.language);
  }

  setupLanguageMessages = (language) => {
    const projectToken = "5e13e3019cff4dc6abe36009445f0883";
    const translationsUrl = `https://cdn.simplelocalize.io/${projectToken}/_latest/${language}`;
    return fetch(translationsUrl)
      .then((data) => data.json())
      .then((messages) => this.setState({language, messages}));
  };

  render() {
    return (
      <LanguageContext.Provider
        value={{
          changeLanguage: (language) => this.setupLanguageMessages(language)
        }}>
        <IntlProvider
          locale={this.state.language}
          messages={this.state.messages}>
          {this.state.messages ? this.props.children : null}
        </IntlProvider>
      </LanguageContext.Provider>
    )
  }
}

export default SimpleLocalize;

This wrapper will keep translations in our LanguageContext and it will also provide a function to change language in fly.

Project translationsUrl variable

Create a SimpleLocalize.io project to get your unique messages variable. For this demo project you can use the messages from the example above!

Activate react-intl in application

Now lets use our newly created SimpleLocalize wrapper to provide translations for React application

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import SimpleLocalize from "./SimpleLocalize";

ReactDOM.render(
    <SimpleLocalize>
      <App/>
    </SimpleLocalize>,
  document.getElementById('root')
);

Done! React will now fetch translations from SimpleLocalize CDN and provide them to your app. Let's check how to use it in the source code.

Using translations in the app

Now, let's use translations, and create very simple web page.

Usage

Checkout how use it.

import React from 'react';
import logo from './logo.svg';
import './App.css';
import {FormattedMessage} from "react-intl";
import LanguageContext from "./LanguageContext";

function App() {

  return (
    <LanguageContext.Consumer>
      {context => (<div className="App">
        <header className="App-header">
          <div>
            <p>
              <FormattedMessage id="USE_BUTTONS_BELOW"/>
            </p>
            <button onClick={() => context.changeLanguage("en")}>English</button>
            <button onClick={() => context.changeLanguage("es")}>Spanish</button>
            <button onClick={() => context.changeLanguage("pl")}>Polish</button>
            <hr/>
          </div>

          <img src={logo} className="App-logo" alt="logo"/>
          <p>
            <FormattedMessage id="DESCRIPTION"/>
          </p>

          <a
            className="App-link"
            href="https://simplelocalize.io"
            target="_blank"
            rel="noopener noreferrer"
          >
            <FormattedMessage id="LEARN_MORE"/>
          </a>
        </header>
      </div>)}
    </LanguageContext.Consumer>
  );
}

export default App;

Using <FormattedMessage/> in application code

<FormattedMessage/> usage is very easy:

<FormattedMessage id="YOUR_TRANSLATION_KEY/>

React will convert FormattedMessage tag into span tag and put concrete translation into it. You can also use <FormattedHTMLMessage id="TRANSLATION_WITH_CSS"/> which will also produce message with HTML inside span tag. Example translation key could look like following:

TRANSLATION_WITH_CSS = This is my <strong>text</strong>

Switching between languages

In presented example I used LanguageContext.Consumer to provide function. This function can trigger language change and fetch proper messages from the CDN.

 <LanguageContext.Consumer>
      {context => (<div className="App">
        <header className="App-header">
          <div>
            <p>
              <FormattedMessage id="USE_BUTTONS_BELOW"/>
            </p>
            <button onClick={() => context.changeLanguage("en")}>English</button>
            <button onClick={() => context.changeLanguage("es")}>Spanish</button>
            <button onClick={() => context.changeLanguage("pl")}>Polish</button>
            <hr/>
          </div>
          //...
        </header>
      </div>)}
    </LanguageContext.Consumer>

You need Language.Consumer tag only in places where you would like to change the language. It's not needed for <FormattedMessages/> tags.

Let's check it!

Notice that translation is done in realtime! How cool is that? Very cool!

React Localization with i18next

Checkout live version

Project code is available on GitHub.

FormatJS and React application localization

Share
Create
Post
simplelocalize advertsimplelocalize cli advert