Norbert Suski

Senior Frontend Developer

Apr 01, 2020 in Development

How to translate React application with react-i18next

Making web applications that support multiple languages is always a challenge, especially when we are talking about apps with currencies, numbers with formats that depend on user language, etc. Today I'm going to show you how to make the first step on the way to translate your web application.

Let's setup our environment first

First thing I did here was to create simple web application using create-react-app tool. This is the application we will be working on. Next thing is to install necessary packages. We are going to use i18next-react library, so we need to add it to the project with following command:

npm install react-i18next i18next --save

Ok, now we are ready to implement i18n into our application.

Setting up translation engine

First let's create new file called i18n.js in src folder which will contain all logic regarding translation engine. Very basic version of the code will look like this:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

i18n
  .use(initReactI18next)
  .init({
    fallbackLng: 'en'
  });

export default i18n;

What is happening here? We are importing required libraries and than we need to extend core functionalities from i18next with React superpowers - here comes the react-i18next. In next lines we are telling i18next instance that it's going to work with React (use(initReactI18next)), and on init we can configure some options (more about them later). Next step is to import this file in index.js file like this:

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

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

Right now nothing will really happen because we have nothing to translate in our application, yet.

Translating application

Let's go to the App.js file and simplify it a little bit.

import React from 'react';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <p>
          We are going to translate this paragraph - how will it be in Polish?
        </p>
      </header>
    </div>
  );
}

export default App;

We are going to translate the only paragraph in this code example. Actually we can do this in many different ways provided by react-i18next, but I'm going to describe only two the most basic ones. Let's start from my favorite - using React hooks.

useTranslation hook

This is the way I prefer the most when I'm implementing functional components. Let's make some changes in our App.js in order to use the hook.

import React from 'react';
import { useTranslation } from 'react-i18next';
import './App.css';

function App() {
  const { t } = useTranslation();
  return (
    <div className="App">
      <header className="App-header">
          <p>{t('translated-paragraph')}</p>
      </header>
    </div>
  );
}

export default App;

What changed here? I imported useTranslation hook from react-i18next library and called it in component's body. This gives me function that I use in paragraph. When using function we need to provide the key of text we want to display here. Whoa whoa! What the heck is key here?! - you may ask. Well, when we create translations in many different languages we want to have the same keys that identify the texts we want to display in this particular place.

If you save the file now you will see error informing you, that useTranslation hook is using React Suspense, but for the sake of simplicity we are not going to use it now. Let's fix this problem by adding required and missing translations in i18n.js file.

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

const resources = {
  en: {
    translation: {
      "translated-paragraph": "We are going to translate this paragraph - how will it be in Polish?"
    }
  },
  pl: {
    translation: {
      "translated-paragraph": "Przetlumaczymy ten paragraf - jak to bedzie po Polsku?"
    }
  }
};

i18n
  .use(initReactI18next)
  .init({
    resources,
    lng: 'pl',
    fallbackLng: 'en'
  });

export default i18n;

I added const resources with two languages: english and polish. Take a closer look at the format of this object which is understandable by i18next. Do you see also "translated-paragraph" key in this object? This is what I meant with the keys that identify translated text across the different languages. In options of i18n instance I added lng with value 'pl'. When you save the file now you should see the paragraph in polish language. Change lng to 'en' and text will change to english one. Interesting thing is fallbackLng - if some translations will be missing - application will automatically use translation from language passed as a value to this parameter.

Important tip here: in real world resources object will be moved to json files, as you can imagine there will be probably hundreds of lines per language used so keeping it like this is quite hard.

Ok, so what is the different option of translating texts?

Higher-Order Component - withTranslation

I will modify App.js file to get the same results but with different approach using HOC.

import React from 'react';
import { withTranslation } from 'react-i18next';
import './App.css';

function App({ t }) {
  return (
    <div className="App">
      <header className="App-header">
          <p>{t('translated-paragraph')}</p>
      </header>
    </div>
  );
}

export default withTranslation()(App);

As you can see here, when we wrap component with withTranslation HOC, we are getting function as property passed to component. Key difference between hook approach and HOC approach is quite obvious - hook cannot be used in class component, there we can use HOC.

Summary

I hope you now have some basic knowledge how to set up your application to use translations engine. I'm awared that things I showed you in this article are just an introduction to this topic, that's why I really want to encourage you to take a closer look at official react-i18next documentation (which is quite good by the way). Do some experiments - like changing language on click, it's really simple to do with the code we already made!

Do you need more information about this topic?

Schedule a call with our developers

Let's talk!

Back to top