DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 966,904 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for How To Add Multiple Language Support In ReactJS
Jasur Kurbanov
Jasur Kurbanov

Posted on

How To Add Multiple Language Support In ReactJS

Introduction

In this tutorial, we will learn how to add multiple language support with react-i18next library in React project.

react-i18next is a powerful internationalization framework for React / React Native which is based on i18next.

Table Of Content

  1. Create New Project
  2. Development
  3. Adding Translations
  4. Language Switcher
  5. Translation Optimization
  6. Final Result
  7. Reference

Demo

Result Demo

Create New Project

Step 1: Run code below to create new React project.

npx create-react-app react-lang-support
Enter fullscreen mode Exit fullscreen mode

Once project created, check if it working by running this code

cd react-lang-support
npm start
Enter fullscreen mode Exit fullscreen mode

Project opened successfully

IProject init

Step 2: Install dependencies
Run code below to install two libraries react-i18next and i18next

npm install react-i18next i18next
Enter fullscreen mode Exit fullscreen mode

react-i18next - is an internationalization-framework for React and React Native which is based on i18next
i18next - is an internationalization-framework written in and for JavaScript

Development

Step 1: First we need to create new file called i18n.js in our project

i18n File

Step 2: Add following code inside i18n.js file

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

i18n
    .use(initReactI18next) // passes i18n down to react-i18next
    .init({
        // the translations
        // (tip move them in a JSON file and import them,
        // or even better, manage them via a UI: https://react.i18next.com/guides/multiple-translation-files#manage-your-translations-with-a-management-gui)
        resources: {
            en: {
                translation: {
                    "Welcome to React": "Welcome to React and react-i18next"
                }
            }
        },
        lng: "en", // if you're using a language detector, do not define the lng option
        fallbackLng: "en",

        interpolation: {
            escapeValue: false // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
        }
    });
Enter fullscreen mode Exit fullscreen mode

Now our file look like this

i18n file result

Step 3: Now we need to make our translation file accessible throughout our project. That's why we need to import i18n.js file inside index.js

Add code below inside index.js

import "./i18n"
Enter fullscreen mode Exit fullscreen mode

Check if you correctly following tutorial by looking to this screenshot below
Check for correctness

Inside i18n.js file, there is translation object which is consist of keys and values. From here we will use these keys inside our JSX file.

Step 4: Inside App.js file lets import useTranslation hook.

import { useTranslation } from 'react-i18next';

function App() {
 return (
    ...
  )
}
Enter fullscreen mode Exit fullscreen mode

useTranslation - gets the t function and i18n instance inside your functional component.

Step 5: As it stated above we will get t function from useTranslation hook inside App component

function App() {
  const { t } = useTranslation()

  return (
    ...
   )
}
Enter fullscreen mode Exit fullscreen mode

Step 6: Now we can use t function inside our JSX. t function looks for key t('key') from i18n.js file. Our keys located inside translation object..

Overall our App.js look like this

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

function App() {
  const { t } = useTranslation()
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          {t('Welcome to React')}
        </a>
      </header>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Check what we have done until this part

npm start
Enter fullscreen mode Exit fullscreen mode

Result

One Language Result

As you can see, we got "Welcome to React and react-i18next" text from our i18n.js file. It means we successfully configured react-i18next and now ready for adding translations.

Adding translations

In this project, three languages will be used. They are Uzbek, Russian and English.
Step 1 For demonstration purposes add following translations inside i18n file.

resources: {
            uz: {
                translation: {
                    welcome: "Xush kelibsiz",
                    goodbye: "Xayr"
                }
            },
            ru: {
                translation: {
                    welcome: "Π”ΠΎΠ±Ρ€ΠΎ ΠΏΠΎΠΆΠ°Π»ΠΎΠ²Π°Ρ‚ΡŒ",
                    goodbye: "Π”ΠΎ свидания"
                }
            },
            en: {
                translation: {
                    welcome: "Welcome",
                    goodbye: "Goodbye"
                }
            }

       }
Enter fullscreen mode Exit fullscreen mode

Now our i18n file look like this

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

i18n
    .use(initReactI18next) // passes i18n down to react-i18next
    .init({
        // the translations
        // (tip move them in a JSON file and import them,
        // or even better, manage them via a UI: https://react.i18next.com/guides/multiple-translation-files#manage-your-translations-with-a-management-gui)
        resources: {
            uz: {
                translation: {
                    welcome: "Xush kelibsiz",
                    goodbye: "Xayr"
                }
            },
            ru: {
                translation: {
                    welcome: "Π”ΠΎΠ±Ρ€ΠΎ ΠΏΠΎΠΆΠ°Π»ΠΎΠ²Π°Ρ‚ΡŒ",
                    goodbye: "Π”ΠΎ свидания"
                }
            },
            en: {
                translation: {
                    welcome: "Welcome",
                    goodbye: "Goodbye"
                }
            }

        },
        lng: "en", // if you're using a language detector, do not define the lng option
        fallbackLng: "en",

        interpolation: {
            escapeValue: false // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
        }
    });
Enter fullscreen mode Exit fullscreen mode

Now let see result on browser.

Only English Translation

As you can see it is showing words from our i18n file. But it is showing only English version.

Let change to Russian language. In order to do this, let's make change key lng to ru inside i18n file

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

i18n
    .use(initReactI18next) // passes i18n down to react-i18next
    .init({
        // the translations
        // (tip move them in a JSON file and import them,
        // or even better, manage them via a UI: https://react.i18next.com/guides/multiple-translation-files#manage-your-translations-with-a-management-gui)
        resources: {
            uz: {
                translation: {
                    welcome: "Xush kelibsiz",
                    goodbye: "Xayr"
                }
            },
            ru: {
                translation: {
                    welcome: "Π”ΠΎΠ±Ρ€ΠΎ ΠΏΠΎΠΆΠ°Π»ΠΎΠ²Π°Ρ‚ΡŒ",
                    goodbye: "Π”ΠΎ свидания"
                }
            },
            en: {
                translation: {
                    welcome: "Welcome",
                    goodbye: "Goodbye"
                }
            }

        },
        lng: "ru", // change here
        fallbackLng: "en",

        interpolation: {
            escapeValue: false // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
        }
    });

Enter fullscreen mode Exit fullscreen mode

Let see result

Russian Translation Result

As you can see it's showing Russian translation on screen. Wow we did it. Congratulations! So if you need Uzbek translation just change lng to uz. But question arises will be every time change language like in this hardcoded way ?

Answer is No. We will implement switcher to our project.

Language Switcher

Step 1: Inside App.js add <select> tag in order to give options for choosing language for user.

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

function App() {
  const { t } = useTranslation()
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>

        <select>
          <option>Choose language</option>
          <option value="uz">Uzbek</option>
          <option value="ru">Russian</option>
          <option value="en">English</option>
        </select>

        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          {t('welcome')}
          <br />
          {t('goodbye')}
        </a>


      </header>
    </div>
  );
}

export default App;

Enter fullscreen mode Exit fullscreen mode

Now user will be able to choose language from <select> dropdown. But it won't change language since we didn't implement function for changing language. In order to change language we will get instance of i18n from useTranslation hook.

Basic syntax of changing language using i18n

i18n.changeLanguage('en-US');
Enter fullscreen mode Exit fullscreen mode

Step 2: We need to get instance of i18n from 'useTranslation'

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

Now inside <select> tag add onChange method, this is where we get values from options provided and pass it to i18n to change language

    <select onChange={(e) => i18n.changeLanguage(e.target.value)}>
          <option>Choose language</option>
          <option value="uz">Uzbek</option>
          <option value="ru">Russian</option>
          <option value="en">English</option>
    </select>
Enter fullscreen mode Exit fullscreen mode

Final App.js

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

function App() {
  const { t, i18n } = useTranslation()
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>

        <select onChange={(e) => i18n.changeLanguage(e.target.value)}>
          <option>Choose language</option>
          <option value="uz">Uzbek</option>
          <option value="ru">Russian</option>
          <option value="en">English</option>
        </select>

        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          {t('welcome')}
          <br />
          {t('goodbye')}
        </a>


      </header>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Result

video1109257644

Translation optimization

Step 1: Now, did you noticed our translations are located inside i18n.js file. We haven't yet started splitting translations into multiple files (which is highly recommended for larger projects) but we already see that adding more languages would result in bundling unneeded translations into the application.

In order to separate our translation we will use package namely i18next-http-backend, which helps us to load our translations
asynchronously.

Install i18next-http-backend by running this code on terminal

npm install i18next-http-backend
Enter fullscreen mode Exit fullscreen mode

Now we need to wire up i18next-http-backend into our i18n.js file

import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import backend from "i18next-http-backend";  // <--- import here

i18n
    .use(initReactI18next) // passes i18n down to react-i18next
    .use(backend) // <--- wire up here 
    .init({
        // the translations
        // (tip move them in a JSON file and import them,
        // or even better, manage them via a UI: https://react.i18next.com/guides/multiple-translation-files#manage-your-translations-with-a-management-gui)
        resources: {
            uz: {
                translation: {
                    welcome: "Xush kelibsiz",
                    goodbye: "Xayr"
                }
            },
            ru: {
                translation: {
                    welcome: "Π”ΠΎΠ±Ρ€ΠΎ ΠΏΠΎΠΆΠ°Π»ΠΎΠ²Π°Ρ‚ΡŒ",
                    goodbye: "Π”ΠΎ свидания"
                }
            },
            en: {
                translation: {
                    welcome: "Welcome",
                    goodbye: "Goodbye"
                }
            }

        },
        lng: "en", // if you're using a language detector, do not define the lng option
        fallbackLng: "en",

        interpolation: {
            escapeValue: false // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
        }
    });
Enter fullscreen mode Exit fullscreen mode

Once we connected i18next-http-backend, by default it will load translation from this path

'../public/locales/{lang}/translation.json'
Enter fullscreen mode Exit fullscreen mode

This path considered to be the default for the i18next-http-backend to load from.

Step 2: We need to create this path locales/{lang}/translation.json inside public folder.

Locales path

Now we need to remove this part of code from i18n.js file

Removed part of code

And add our translations inside translation.json file for each language.

UZ
Uzbek
RU
Russian
EN
English

Now check result on browser

Final Result

Final Result

Link to full source of tutorial here

Reference list

i18next
React.i18next
Locize
Geeksforgeeks
Legacy-v9

Top comments (1)

Collapse
 
mustafinho profile image
Kevin Bravo

β€πŸ’šπŸ’šπŸ’š love it

In defense of the modern web

I expect I'll annoy everyone with this post: the anti-JavaScript crusaders, justly aghast at how much of the stuff we slather onto modern websites; the people arguing the web is a broken platform for interactive applications anyway and we should start over;

React users; the old guard with their artisanal JS and hand authored HTML; and Tom MacWright, someone I've admired from afar since I first became aware of his work on Mapbox many years ago. But I guess that's the price of having opinions.