ReactIntl and ReactJS interantionalization with SimpleLocalize.io

jpomykala

Jakub Pomykała

Posted on November 20, 2020

ReactIntl and ReactJS interantionalization with SimpleLocalize.io

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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')
);
Enter fullscreen mode Exit fullscreen mode

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;

Enter fullscreen mode Exit fullscreen mode

Using <FormattedMessage/> in application code

<FormattedMessage/> usage is very easy:

<FormattedMessage id="YOUR_TRANSLATION_KEY/>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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!

formatjs_and_react_app_localization

Checkout live version

Project code is available on GitHub.

💖 💪 🙅 🚩
jpomykala
Jakub Pomykała

Posted on November 20, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related