DEV Community

Cover image for Internationalizing your React app with i18next
Ary Barros
Ary Barros

Posted on • Edited on

Internationalizing your React app with i18next

Nowadays, our applications have taken on proportions never before imaginable, and the web has given us the possibility to make it accessible all over the world. This is where many developers face a problem...

How do I get my app translated quickly and efficiently?

To our happiness, libraries like React have extremely easy alternatives to implement this functionality, and today, we are going to meet one of them, the i18next plugin.

Implementing internationalization

To start, let's go to our facilities. If you want to start an app from scratch, let's use the command below and create a new react app:

yarn create react-app i18napp --template typescript
Enter fullscreen mode Exit fullscreen mode

If you already have a project or have just created yours, install the dependencies that we will need for i18next to work properly:

yarn add react-i18next i18next i18next-http-backend i18next-browser-languagedetector
Enter fullscreen mode Exit fullscreen mode

Okay, now we already have the packages we need. Let's get your hands on the code!!!

Configuring i18next

To indicate to our app the use of internationalization and properly activate the hooks in it, we must prepare a file that will be next to our index.js, it will be called i18n.js and will contain the following lines:

import i18n from 'i18next'
import Backend from 'i18next-http-backend'
import LanguageDetector from 'i18next-browser-languagedetector'
import { initReactI18next } from 'react-i18next'

i18n
  // Enables the i18next backend
  .use(Backend)
  // Enable automatic language detection
  .use(LanguageDetector)
  // Enables the hook initialization module
  .use (initReactI18next)
  .init({
    // Standard language used
    fallbackLng: 'en',
    debug: true,
    //Detects and caches a cookie from the language provided
    detection: {
      order: ['queryString', 'cookie'],
      cache: ['cookie']
    },
    interpolation: {
      escapeValue: false
    }
  })

export default i18n;
Enter fullscreen mode Exit fullscreen mode

After that, we should import it into our index.js, which will look like this:

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

ReactDOM.render (
  <React.StrictMode>
    <Suspense fallback={<div>Loading...</div>}>
        <App />
    </Suspense>
  </React.StrictMode>,
  document.getElementById('root')
);

serviceWorker.unregister();
Enter fullscreen mode Exit fullscreen mode

All set, react i18next is enabled and ready to use. Now the next step is to incorporate our translations.

Incorporating locales

Internationalizations on the web work on the basis of json with word sections. In this app, we will incorporate English and Portuguese.

For this, in our /public folder we will add the /locales folder that will have two subfolders, /en and /pt, both with a translation.json file that will contain the object with the translations. See an example of the file in English and the structure of the produced folder:

{
  "title": "Welcome to an internationalized APP",
  "description": {
    "part1": "To get started, edit <1>src/App.js</1> and save to reload.",
    "part2": "Switch language between english and portuguese using buttons above."
  }
}
Enter fullscreen mode Exit fullscreen mode

Locales folter structure

Alt Text

That done, let's get down to business with our homepage.

Customizing the App.js

Now let's go to our final part, building our home page. For this, we will delete the original content of App.js and leave only one div.

Importing the translation hook

To import the i18next hook we use the following code:

import {useTranslation} from "react-i18next";

function App () {
  const {t, i18n} = useTranslation ();
Enter fullscreen mode Exit fullscreen mode

The t attribute is used to incorporate our translation and i18n to observe changes in the state of the localization.

Using translation in tags

To use an attribute of our object, we just call the t() function that we have destructured above:

   <div><h1>{t("title")}</h1></div>
Enter fullscreen mode Exit fullscreen mode

See how easy it is?

We will complete our app with the code below by adding two buttons that will change the language and see the magic in real time...

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

function App() {
  const { t, i18n } = useTranslation();

  const changeLanguage = (language) => {
    i18n.changeLanguage(language);
  };

  return (
    <div className="App">
      <button onClick={() => changeLanguage("en")}>EN</button>
      <button onClick={() => changeLanguage("pt")}>PT</button>
      <hr />
      <div><h1>{t("title")}</h1></div>
      <div>{t("description.part1")}</div>
      <div>{t("description.part2")}</div>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Observing the magic

If you entered the code correctly, the magic below should happen to your app. Translation is done at runtime.

Alt Text

Did you liked? The code is available on my github.

Thanks for reading!!!

Top comments (10)

Collapse
 
alexandrudanpop profile image
Alexandru-Dan Pop

Nice article. i18next is also my go-to library, very nice ecosystem, and has libraries for all major frameworks.

Collapse
 
aryclenio profile image
Ary Barros

i18next is a very interesting library. Nowadays in react it just competes with react-intl but i18next is far more intuitive and fast.

Collapse
 
jpomykala profile image
Jakub Pomykała • Edited

I personally chose react-intl because it was much simpler to use on the beginning, but so far I didn't spot any issues with that, even on complex systems. It's simple and good enough to do the job. :) That's why I'm happy that I found your post about i18next, so I was able to see how to setup it quickly

Collapse
 
monfernape profile image
Usman Khalil

Good one. Bring more

Collapse
 
aryclenio profile image
Ary Barros

Thanks Usman Khalil! :)

Collapse
 
florensadi profile image
💎

Thank You!!

Collapse
 
aryclenio profile image
Ary Barros

Thank you for reading florensadi :D

Collapse
 
jpomykala profile image
Jakub Pomykała

Hi, thanks for the simple solution! You can follow my profile to check how to solve localization problems in more complex systems 👍

Collapse
 
aryclenio profile image
Ary Barros

Thanks Jakub. Following you :)

Collapse
 
adrai profile image
Adriano Raiano

Hehe.... I like to observe the magic 😉

Here you can observe even more i18next magic: dev.to/adrai/how-to-properly-inter... 👀