FormatJS and React application localization

Jakub Pomykała
Jakub Pomykała
Last updated: September 23, 20247 min read
FormatJS and React application localization

React localization is one of the topics discussed vividly among developers. There are many i18n libraries built for React, React Native, and NextJS, that focus on app internationalization. Website or app translation is so important because it positively affects the product visibility and performance, increases the customer base and satisfaction by creating a special relation. It's all thanks to adjusting the product to their language, customs, and culture. Developers have a great choice of tools and libraries that can help them in i18n of the product, and one of them is FormatJS. 

About FormatJS

FormatJS, originally yahoo/react-intl, is a localization and internationalization set of libraries built mainly for React apps. It helps in i18n process, focusing on numbers, dates, and strings formatting. It provides i18n tools and packages that help with localization and app translation management.

A sample i18n file structure in FormatJS looks like this: 

projectRoot
|-- src
|   |-- App.js
|-- lang
|   |-- en-US.json
|   |-- fr.json
|-- package.json
|-- .eslintrc.js

In lang we create json files with supported languages, for example, en-US or fr. FormatJS focuses or improving development process of app internationalization and helps in future translation management.

How to translate React app with FormatJS?

The installation and translation process is quite straightforward. We will start with creating a sample project, then FormatJS installation and setup, and finally building and translating our app. Sounds fun, right? 😎

Create a sample project

Let's start with something simple. I will create a new project using create-react-app. Use NPM or Yarn like in the example below.

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

Or download the demo app from GitHub repository.

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 real-time.

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 for i18n with react-intl and SimpleLocalize wrapper.

// 📦 file: ./SimpleLocalize.js

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.

Translate your app with FormatJS and SimpleLocalize

Now, it's time to work on i18n and localization process. We use SimpleLocalize to extract translation keys and as a translation management and i18n online editor.

Create project

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

Wrap your application

Now let's use our newly created SimpleLocalize wrapper to provide translations for React application.

// 📦 file: ./index.js

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.

Translating React app

Now, let's start using translations, and create a basic web page.

FormatJS setup

See below how to apply translations for your React app. For that, we will use FormattedMessage component which wraps up all translation keys.

// 📦 file: ./App.js

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;

FormattedMessage component

<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 a message with HTML inside span tag.

A sample translation key could look like the following:

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

Switch between languages

In the 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 try it!

Note that translation works in real-time! How cool is that? Very cool!

React Localization with FormatJS

See live version

Project code is available on GitHub.

Translation management for FormatJS

FormatJS is a great tool for translating your React app. It is intuitive and not too complicated to introduce to your project. Using react-intl together with SimpleLocalize can really speed up the translation process with great auto translation tools (OpenAI, DeepL or Google Translate), many integrations and easy to use i18n online editor. It's a great help in development process thanks to SimpleLocalize CLI for FormatJS, which extracts all translation keys from your project with a simple command.

i18n online editor

Check our docs for FormatJS integration in SimpleLocalize and translate your app in our feedback-driven app. Get in touch or send us your feedback at [email protected].

Jakub Pomykała
Jakub Pomykała
Founder of SimpleLocalize