Understanding React Internationalization

Pieces 🌟 - Aug 29 '23 - - Dev Community

Whether you're creating solutions for web applications or mobile applications, a common factor in the development process is ensuring user satisfaction — ideas and implementations are created mainly to improve user experience, especially when building industry-standard applications. So, rather than asking "What other feature can I add to this application?", the appropriate question should be "What other feature will the user want in this application?" This is a very effective approach in aiming for maximum application scalability — putting the users first.

That said, a lot of factors are considered in ensuring users are getting the best of the application, one of which is grammatical comprehension by other demographics. This is a key development stage many developers tend to miss out on when creating solutions. What do I mean by this? Saying "Hello World" will be well understood by an English user, not so much for a Spanish user because then you have to say "Hola Mundo", or "Bonjour le monde" for a French user, and different lexical syntax for other languages. But how do you implement this? That's where the term Internationalization is put to use.

In this tutorial, you will learn about React Internationalization, its use case, and how to use it in your application.

Prerequisites

This tutorial will break the in-depth concepts of React Internationalization into very simple terms. However, you must know of the following:

What is React Internationalization?

Just before we get to React Internalization, a definition of the term "internationalization" is required. Internationalization is loosely referred to as i18n, meaning 18 for the number of characters between "i" and "n". It is the process of adding support for other languages and cultural settings in your application. In addition to providing the language translation, internationalization entails providing equivalents for the date and time format and number format.

As you would guess, React Internationalization is the process of implementing the functionalities of internationalization with React. Quite interesting, isn't it?

The Need for React Internationalization

Implementing Internationalization is important in many ways, some of which include:

  • ease of application usage by users of different languages.
  • the wide and global reach of a product.
  • breaking the application scalability obstacles caused by language barriers.

How Does it Work?

Throughout this article, we will implement React Internationalization using a sample project, but hold on, what really happens behind the scenes? How does our application know the language of the users? More importantly, how does it know what language to translate it to? The process of Internationalization can be broken down into three stages:

  1. Detecting the user's location: To know what content (or language) to display to the user, the first step is to know the location of the user. With that, you also know the language they speak and ultimately choose from the range of languages to display.
  2. Translating UI elements: After successfully detecting the location of the user, what we would want to do next is to translate key aspects of the application to the language of the user. For instance, the "Home" page, which takes the English user to the root page of the application now becomes the "Hogar" page for the Spanish user, which runs the same function.
  3. Translating location-specific content: Internationalization does not only entail the translation of languages but also other content like dates, currencies, number format, etc. Dollars is the official currency of the United States but this would be confusing to a Japanese user because you would then have to spend the Yen, which is the official currency of Japan. Further, Japan is 13 hours ahead of the United States, so there has to be a dynamic display of date and time based on the location of the user.

Now that we know the raw process of internationalization, how do we implement the functionality using React?

Getting Started

To ease the implementation of internationalization, there are React packages such as react-i18next which is used for React or React Native applications. It provides multiple components that handle the translation of elements or content based on a given user location. Let's see how we would set this up.

Scaffolding your React Application

  1. Let's start by creating a sample file named i18n-pieces-tutorial which we will be working on. We will be using Next.js as our build tool. Open your terminal and run the line of code:
npx create-next-app i18n-pieces-tutorial
Enter fullscreen mode Exit fullscreen mode
  1. Next, change the directory and run the server. This runs the application in our browser.
cd i18n-pieces-tutorial
npm run dev
Enter fullscreen mode Exit fullscreen mode
  1. Install the dependencies. As we learned earlier, React provides a framework which can be used for Internationalization. We will install three packages; i18next package (the general library), the react-i18next package (specifically for React or React Native applications), and the i18next-browser-language-detector (to detect the user's language). We do that by running the following line of code:
npm install i18next react-i18next i18next-browser-languagedetector
Enter fullscreen mode Exit fullscreen mode

And that's it with the set-up!

Creating a Demo Translation Project

Configuring i18n for Next.js

Let's create a sample project in English, which we will then use to implement translation functionalities in other languages. But before we do that, we need to configure our i18n package. Suppose we want to implement an English-to-French translation functionality:

// i18n.js file
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";

i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
  debug: true,
  fallbackLng: "en",
  interpolation: {
    escapeValue: false,
  },
  resources: {
    en: {
      translation: {
        description: {
          useCaseOne: "Copy and save code snippets with Pieces App.",
          useCaseTwo:
            "Translate from one programming language to another using the Pieces App",
          useCaseThree: "Generate code snippets using Pieces Co-Pilot",
        },
      },
    },
    fr: {
      translation: {
        description: {
          useCaseOne:
            "Copiez et enregistrez des extraits de code avec l'application Pieces.",
          useCaseTwo:
           "Traduire d'un langage de programmation à un autre à l'aide de l'application Pieces",
          useCaseThree:
           "Générez des extraits de code à l'aide de Pieces Co-Pilot.",
          },
        },
      },
     },
  });

export default i18n;
Enter fullscreen mode Exit fullscreen mode

Here, we import i18n from the i18next package, initReactI18next from the react-i18next package, and LanguageDetector from the i18next-browser-languagedetector package. Next, we initialize i18n by passing in the resources(which contains the language translation instances), the lng(which specifies the language we want to display at that instance), the fallbackLng(which specifies the default language to display if no language is recognized) and the interpolation, which is responsible for displaying dynamic values in translations, It is mostly used in displaying date and time values according to the user's location.

In our resources object, we give instances for our text in English using the en keyword and its equivalent in French using the fr keyword. Using the language detector, the text in English is displayed to English users while text in French is displayed to French users. We pass in three texts in our en object using useCaseOne, useCaseTwo and useCaseThree which stands for the basic use cases of the Pieces App, they are:

  • Copy and save code snippets with Pieces App.
  • Translate from one programming language to another using the Pieces App.
  • Generate code snippets using Pieces Copilot.

Displaying Translation

After configuring the i18next functionality, let's see what our code looks like in our browser.

import  './i18n';
import { useTranslation } from 'react-i18next';
function App() {
  const { t } = useTranslation();
  return (
   <div>
       <h4>Pieces App</h4>
       <p>{t('description.useCaseOne')}</p>
       <p>{t('description.useCaseTwo')}</p>
       <p>{t('description.useCaseThree')}</p>
   </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Here, we import the React i18n package and useTranslation hook into our App.js file. The i18n package imports the functionality while we use the useTranslation hook to handle translation between languages. The t() method, which is obtained from the useTranslation hook is used to translate texts from one language to another as specified in the i18next file. And so we pass in texts using three use cases of the Pieces App as defined earlier. To learn how to create custom hooks, visit this site.

For English users, this is what is displayed on the screen:

The English version of the displayed message.

For French users, this is displayed:

The French version of the displayed message.

Now we have implemented translations for English and French based on the user's location. We can go further to define translations for other languages.

Interpolation and Pluralization

Interpolation is one of the features of the i18next package. It allows you to input dynamic values in your translations. Pluralization, on the other hand, deals with representing the plural form of words across different languages. With the help of the interpolation feature in React, we can easily implement plural forms by just inputting the number we want, and it automatically reflects in the other languages. For instance, if we want to change "I read the Pieces blog one time every day" to its plural form, we do not have to manually make changes to the sentence, all we have to do is pass the number into a variable and it changes.

You might think, "This isn't so stressful, I can just manually change one to three right?" Well, maybe not so stressful if it is done in the same language, but imagine having to make translations for about 5 languages. That can be tasking. Interpolation allows you to make the change just once, and it reflects in other languages.

Implementing Interpolation and Pluralization

Let's see how this works, you can re-configure the resources object in your i18next file like this:

import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";

i18n
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    debug: true,
    fallbackLng: "en",
    interpolation: {
      escapeValue: false,
    },
    resources: {
      en: {
        translation: {
          description: {
            useCaseOne: "Copy and save code snippets with Pieces App.",
            useCaseTwo:
              "Translate from one programming language to another using the Pieces App",
            useCaseThree: "Generate code snippets using Pieces Co-Pilot",
          },
          interpolation_pluralization: {
            singular: "I read the Pieces blog one time every day",
            plural: "I read the Pieces blog {{count}} times every day",
          },
        },
      },
      fr: {
        translation: {
          description: {
            useCaseOne:
              "Copiez et enregistrez des extraits de code avec l'application Pieces.",
            useCaseTwo:
              "Traduire d'un langage de programmation à un autre à l'aide de l'application Pieces",
            useCaseThree:
              "Générez des extraits de code à l'aide de Pieces Co-Pilot.",
        },
        interpolation_pluralization: {
          singular: "Je lis le blog Pieces une fois par jour",
          plural: "Je lis le blog Pieces {{count}} fois par jour",
        },
      },
    },
  },
});

export default i18n;
Enter fullscreen mode Exit fullscreen mode

In this update, we added the interpolation_pluralization object which specifies the translation based on the quantity passed into the countvariable. If it is singular, it reads "one time" across other languages. If it is plural, it reads "{{count}} times", where count represents the number passed into it.

Displaying Content

Now that we have made the updates in our configuration, we can then display the content. Updating the content in our App.js file, we have:

import "./i18n";
import { useTranslation } from "react-i18next";
function App() {
  const { t } = useTranslation();
  return (
    <div>
      <h4>Pieces App</h4>
      <p>{t("interpolation_pluralization.text", { count: 3 })}</p>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Since we have set the value in our count to three, here's the output for English users:

The English output.

This is what is displayed for French users:

The French output.

Conclusion

By following this tutorial, you have learned the meaning of Internationalization, the need for Internationalization in React, how to translate text from one language to another using the React i18n package, how to configure the React Internationalization packages, the meaning of Interpolation and Pluralization, and how to implement Interpolation and Pluralization in your application.

However, it does not end here, you can explore more by implementing translation to other languages using the react-i18next documentation. The next step would be implementing React localization to refine your application. Have fun!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .