DEV Community

Cover image for From Mono to Multilingual: Supercharge Your React App with i18n
Dileep Reddy
Dileep Reddy

Posted on

From Mono to Multilingual: Supercharge Your React App with i18n

What is i18n?

Imagine you work as a developer at a growing startup, and your manager comes to you and says, "We are going to expand to a new country. In order to interact with local customers, you need to make changes to support their language and local requirements." This process is called internationalization, commonly referred to as i18n because there are 18 letters between "i" and "n" in "internationalization". In this post, we will focus on using the i18next JavaScript package with React.

i18n features

i18n has many use cases, including:

  • Language support
  • Date and time format changes (e.g., DD/MM/YYYY, YYYY/MM/DD)
  • User language detection
  • Currency representation (placement of currency symbol with digits varies by country), and more.

Installation

To use i18n in React, we need to install two packages:

npm i react-i18next i18next --save
Enter fullscreen mode Exit fullscreen mode

The i18next package is the core package that works with all JavaScript frameworks and apps, while react-i18next is a plugin that makes it easy to use i18next with React.

Make React Multilinugual - Setup

Inside your app's src folder, create a new file called i18n.js (you can choose any name). Set up the file as follows:

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

const resources = {} // We'll fill this later

i18n.use(initReactI18next)
    .init({
      resources,
      lng: 'en', // default language option. en for english
      interpolation: {
        escapeValue: false
      }
    })

export default i18n
Enter fullscreen mode Exit fullscreen mode

In the above code, we import the main i18next package and the initReactI18next class. Then we initialize the i18n class by passing the configuration data.

The resources object is where we store the translations for different languages. The interpolation key is used to prevent cross-site scripting attacks. The escapeValue is set to false because the safety check is enabled in React by default, and we don't want i18n to perform the check again as it may slow down the application.

Next, import this file into src/index.js as follows:

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

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
Enter fullscreen mode Exit fullscreen mode

Now you are ready to use it in the Components. Let's create a component called Home.js with the following code.

import React from 'react'
import { useTranslation } from 'react-i18next';

const Home = () => {
  const { t } = useTranslation()

  return (
    <div className='App-header'>
      <p>{t('home_text')}</p>
    </div>
  )
}

export default Home
Enter fullscreen mode Exit fullscreen mode

Our app should look like this now. As we did not add any language resources in i18n.js. The key name will be displayed.

Multilingual React

Let's go and update both i18n.js and Home.js

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

const resources = { // language specific data
  en: {
    translation: {
      'home_text': 'This is my home page',
      'ask user': 'How are you?'
    }
  },
  de: {
    translation: {
      'home_text': 'Dies ist meine Homepage'
    }
  }
}

i18n.use(initReactI18next)
    .init({
      resources,
      lng: 'en', // default language option. en for english
      interpolation: {
        escapeValue: false
      }
    })

Enter fullscreen mode Exit fullscreen mode
const Home = () => {
  const { t } = useTranslation()

  return (
    <div className='App-header'>
      <p>{t('home_text')}</p>
      <p>{t('ask user')}</p>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

In the above code, we use the useTranslation hook from react-i18next to access the translation function t(). We can use t('home_text') to retrieve the translated text for the key home_text.

Now our app should look like this

Multilingual React

Switch Language

To switch between languages, react-i18next provides an i18n instance with several methods. Let's update Home.js to include language switching:

const Home = () => {
  const { t, i18n } = useTranslation()
  const languages = {
    en: 'English',
    de: 'German'
  }

  return (
    <div className='App-header'>
      <p>{t('home_text')}</p>
      <p>{t('ask user')}</p>
      <div>
        { Object.keys(languages)
                .map((lng) => <button
                                onClick={() => i18n.changeLanguage(lng)}
                                disabled={i18n.resolvedLanguage == lng}
                                key={lng}
                              >
                                {languages[`${lng}`]}
                              </button>
                    )}
      </div>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

With the above code you can switch between languages by using the provided buttons.

But there is a problem, when you switch to german instead of displaying the greeting it'll display the key name like this.

Multilingual React

Fallback Language

To handle missing translation keys, we can specify a fallback language. Update the i18n.init call in i18n.js as follows:

i18n.use(initReactI18next)
    .use(LanguageDetector)
    .init({
      resources,
      lng: 'en',
      interpolation: {
        escapeValue: false
      },
      debug: true, // Will display debug options in console
      fallbackLng: 'en' // If any key is missing, it will fallback to english
    })
Enter fullscreen mode Exit fullscreen mode

Language Detection

Providing an option to switch languages is good, but we can do better.
To automatically detect the user's preferred language in the browser, we can use the i18next-browser-languagedetector package. Install the package and update i18n.js as follows:

import LanguageDetector from 'i18next-browser-languagedetector';

const languageOptions = {
  order: ['navigator', 'querystring'], // Define order and way to find user preference
  lookupQuerystring: 'lng' // key name to find the preference
}

i18n.use(initReactI18next)
    .use(LanguageDetector)
    .init({
      resources,
      lng: 'en',
      interpolation: {
        escapeValue: false
      },
      detection: languageOptions,
      debug: true,
      fallbackLng: 'en'
    })
Enter fullscreen mode Exit fullscreen mode

We need to import LanguageDetector from the package and pass it during i18n initialisation.
Also we need to pass options for language detection through detection key.

There are many other options which you can pass for language detection which you can find in the documentation

Conclusion

Thank you for reading this blog post on making a React app multilingual using i18n. We covered the basics of i18n, installation, setup, language switching, fallback language, and language detection. Stay tuned for the next part where we'll explore more features provided by i18next.

If you have any corrections or questions, feel free to leave a comment. Thank you again for reading!

Thumbnail Photo by Amador Loureiro on Unsplash

Top comments (0)