How to set up Internationalization in React from start to finish

Globe icon

Internationalization (i18n) allows your web app to support multiple languages and be accessible to users around the world. The React framework makes i18n easy to implement. In this comprehensive guide, you‘ll learn how to setup i18n in React from start to finish using the react-intl library.

Benefits of Internationalization

Here are some of the key benefits of implementing i18n:

  • Reach more users – Supporting multiple languages widens your target audience
  • Enhance UX – Users have better experience in their preferred language
  • Increase conversion rates – Content in native language leads to higher conversions
  • Expand to new markets – Supporting local languages makes entering new regions easier

Overview of react-intl

React Intl is a library that provides React components and an API to format dates, numbers, and strings, including pluralization and handling translations.

Here is what react-intl can do:

  • Aggregate content scattered throughout your app for easy translation
  • Manage translated strings, dates, numbers, etc.
  • Allow dynamic loading of translations

And what it does NOT do:

  • Automatically translate content
  • Detect user‘s locale
  • Fix unrelated app issues

So in summary, react-intl gives you the framework and React components needed to support i18n, but you need to handle the translations.

Project Setup

We‘ll be using create-react-app to setup our project:

npx create-react-app i18n-example
cd i18n-example
npm install react-router-dom react-intl

Our app will have three routes – Home, Day, and Weather.

Configuring react-intl

First, wrap root component in IntlProvider:

<IntlProvider>
  <App /> 
</IntlProvider>

This makes react-intl context available to all child components.

Next, for each translatable text, use the FormattedMessage component:

<p>
  <FormattedMessage    
    id="home.welcome"
    defaultMessage="Welcome Visitor!" 
  />  
</p>
  • id is a unique identifier
  • defaultMessage is the text in default language

The text will be wrapped in a <span> so keep the original HTML/JSX tags.

Do this for ALL translatable content across app.

Extracting Messages

To manage translations effectively, we need all the default messages extracted into JSON files.

Install the Babel plugin:

npm install babel-plugin-react-intl

Configure .babelrc:

{
  "plugins": [
    ["react-intl", {
      "messagesDir": "./translations/"  
    }]
  ]
}

Run build command:

npm run build

This will generate JSON files with messages under /translations.

Combining Message Files

It‘s better to have messages aggregated in one file.

Create mergeMessages.js script:

import { messages } from ‘./translations‘; 

const translations = {
  ‘en‘: messages 
};

fs.writeFileSync(‘./translations.json‘, JSON.stringify(translations));

Modify npm scripts to run this file before build.

Now translations.json will contain all messages.

Adding Translations

Time to translate!

Copy en messages to es.json:

{
  "es": {
    "home.welcome": "¡Bienvenido Visitante!",
    "other.message": "Otro mensaje" 
   }
}

Rerun build script to aggregate translations.

Loading Correct Messages

In index.js, dynamically import translations for user‘s locale:

import esTranslations from ‘./translations_es.json‘;

const locale = detectUserLocale(); // es

ReactDOM.render(
  <IntlProvider locale={locale} messages={esTranslations}>
    <App />
  </IntlProvider>,
  document.getElementById(‘root‘)
);

That‘s it! App now supports multiple languages.

Conclusion

And there you have it – a step-by-step guide to add i18n support to a React app with react-intl.

The key takeaways are:

  • Use IntlProvider to enable i18n context
  • Tag translatable content with FormattedMessage
  • Extract messages into JSON files
  • Translate and combine message files
  • Dynamically load translations

Supporting multiple languages is easier than ever with React. i18n allows you to reach more users worldwide and boost engagement.

I hope you found this guide useful. Let me know in the comments if you have any other questions!

Similar Posts