Easily restore your project to a previous version with our new Instant One-click Backup Recovery

How to Internationalize a React Application Using i18next and Hygraph

In this post, we will take a deep dive into how to internationalize a React Application using i18next and Hygraph.
Joel Olawanle

Joel Olawanle

May 16, 2022
internationalization-of-react-application-hygraph-og

Internationalization (or i18n) is a feature that is used to overcome the language barrier by providing support for several languages to users who use a certain software application or website. Only 25.9 percent of internet users were English speakers as of March 2020, emphasizing the need for multilingual websites and applications and emphasizing that you may be missing out on a substantial percentage of potential users.

In this article, we will see what internationalization is and how to implement it in our React applications with i18next.

#What is Internationalization and why is it Important

Internationalization (or i18n) is the process of ensuring that your website's platforms, processes, and architecture can accommodate and support many languages to allow you to build localized sites/apps. It is also the process of supporting different time zones, date formats, currencies, text directions, and more.

In simple terms, it is the process of ensuring that your website is set up to handle several languages and that your overall website design is capable of accommodating these numerous languages. This helps you to increase your reach to people all over the world.

#Intro to i18next and Why this Library

I18next is a well-known JavaScript Internationalization library, it was developed in 2011 and has been maintained well till now. The main advantage of using this library is that it is quite mature and covers all possible use cases around internationalization, also it is framework agnostic and has more focus on Internationalization in general and not the framework in use, they have integrations available with almost every major framework and frontend/backend technology. So, if you have multiple codebases with different tech stacks or your projects keep changing, you can still use the i18next library across all different projects. Compared to other 18n libraries, i18next is quite mature and provides many features. More information on why i18next is unique can be found here.

Prerequisites

To follow along with this guide and code, you should have:

  • Basic understanding of HTML, CSS, and JavaScript
  • Beginner-level React.
  • Node and npm or yarn installed on your machine.

#Getting Started

First, we'll set up our React application using Create React App (CRA), which is a quick way to start building a new single-page application in React. We can run the following command in our terminal:

npx create-react-app react-i18n-tutorial

Once that is successful, the next step would be to change the directory to the project and then start our server:

cd react-i18n-tutorial
npm start

Installing Dependencies

Next, we can install the dependencies required for our application. We would install two dependencies: i18next (the actual library), react-i18next (the React/React Native internationalization wrapper library). Let’s install all the dependencies at once by running the following command in our terminal:

npm install i18next react-i18next

#Translating Plain Text

Configure i18next

Let’s learn how to translate normal/plain text from one language to another language. First, we need to configure i18next, we would do this by creating a dedicated file i18n.js in the src folder and pasting the following configuration code:

src/i18n.js

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
i18n
.use(initReactI18next)
.init({
resources: {
en: {
translation: {
welcome: {
text: 'Welcome to this React Internationalization App',
},
},
},
fr: {
translation: {
welcome: {
text: "Bienvenue sur cette application d'internationalisation React",
},
},
},
},
lng: 'en',
fallbackLng: 'en',
interpolation: {
escapeValue: false
},
});

In this file, we first imported i18n from i18next and also initReactI18next from react-i18next, a plugin to ensure that i18next works with React. The next step was to initialize i18n by passing it an object of options. There are many configuration options you can pass to the initializer, and we're passing these for now:

  • resources: This contains the different translations that are available. We would eventually relocate our translations to a separate file/folder. Note: These translations contain both the key and the value; we utilize the key to obtain the value afterward. For example, in the above, text is the key, and Welcome to this React Internationalization App is the value of en (English) while Bienvenue sur cette application d'internationalisation React is the value for fr (French).
  • lng: This is used to provide the language we want to show or retrieve from the resources object. You can consider it to be the currently set language for the application.
  • fallbackLng: This option defines the fallback language in case some key is not recognized in the current language.
  • interpolation: Interpolation is one of the most commonly utilized features in I18N. It enables you to incorporate dynamic values into your translations. This would later be used to manage date formatting.

Using the t() Function in i18next

At this point, we have fully configured i18next on our React Application. The next step is to manage translations in our application. We need to include the i18n.js file we prepared earlier in our index.js file so it can be utilized throughout our application.

index.js

import './i18n';

Now we can use translations. We utilize the t() method, which is derived from useTranslation and imported from react-i18next. Let's take care of this in our App.js file:

App.js

import { useTranslation } from 'react-i18next';
function App() {
const { t } = useTranslation();
return (
<div>
<h2>{t('welcome.text')}</h2>
</div>
);
}
export default App;

As you can see here, we made use of the key given in the resources file - welcome.text to get the actual value.

At this point when we load (via npm start) our app, we would see an output like this, and when we go to the i18n.js file to change the lng option to fr, the French text would be displayed.

basic.PNG

#Interpolation and Pluralization

Interpolation is one of the most commonly utilized features in i18n. It enables the incorporation of dynamic values into your translations and may be used in conjunction with Pluralization. In English, most plural nouns are produced by adding the s suffix, in many cases even the structure of various sentences can change when working with singular vs plural number of items For example - There is only one Article on this becomes There are 5 Articles on this for its plural. This pluralization is handled effectively by I18next.

To see interpolation in action let us add a new key interpolation_pluralization as shown below, we have configured two sub-keys for text_one and text_other. Here, text_one and text_other are the new entries (see the _other suffix as that of plural and _one as the singular).

resources: {
en: {
translation: {
welcome: {
"text": "Welcome to this React Internationalization App",
},
interpolation_pluralization: {
"text_one": "There is only one Article on this",
"text_other": "There are {{count}} Articles on this"
}
}
},
fr: {
translation: {
welcome: {
"text": "Bienvenue sur cette application d'internationalisation React",
},
interpolation_pluralization: {
"text_one": "Il n'y a qu'un seul article à ce sujet",
"text_other": "Il y a {{count}} articles sur ce sujet"
}
}
},
}

You can check out more examples and explanations here. I18next uses a {{placeholder}} for inserting dynamic values in the translations. We can now update our App.js file to make use of the text key to get the value:

App.js

<div>
<h2>{t('welcome.text')}</h2>
<p>{t('interpolation_pluralization.text', { count: 5 })}</p>
</div>

At this point when we load our app, we would see an output like this, and this would also apply when we change the language:

interpolation.PNG

#Date/Time Translations

This library also helps us with date/time translations and different types of formatting options. It will take care of things like how day names or month names are spelled in different languages and even formatting them differently. First, let us add a key to our configuration for managing the date-time translations

i18n.js

{
en: {
translation: {
...
datetime: "Today is {{val, datetime}}",
}
},
fr: {
translation: {
...
datetime: "Aujourd'hui c'est {{val, datetime}}",
}
}
}

Now in our App.js file all we need to do is to use this datetime key with the t() function

<p>{t('datetime', { date: new Date() })}</p>

We can even pass different formatting options to it, an example is shown below

<p>
{t('datetime',
{
date: new Date(),
formatParams: {
val: { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' },
},
})}
</p>

datetime.png

#Switching Between Languages

We will implement the language-switching feature in this part. We can add buttons that would allow us to switch between languages programmatically. We just need to call i18n.changeLanguage function given by i18next and supply it the language code.

import { useTranslation } from 'react-i18next';
import i18n from 'i18next';
function App() {
const lngs = [
{ code: 'en', nativeName: 'English' },
{ code: 'fr', nativeName: 'Francais' },
];
const { t } = useTranslation();
return (
… existing code
<div>
{lngs.map((lng) => {
return (
<button
className="m-4 p-2 bg-blue-600 rounded"
key={lng.code}
type="submit"
onClick={() => i18n.changeLanguage(lng.code)}
>
{lng.nativeName}
</button>
);
})}
</div>
… existing code
);
}
export default App;

Once this is done, and we load our app, the buttons will now appear and we can change the languages easily as seen below:

#Lazy Loading Translation Files

So far, we have been retrieving translations from our i18n.js file, which works great but is unsuitable for real-world applications with lots of translation keys. We can split these translations for different languages into dedicated JSON files, and lazy load them on demand. To do so, we'll need to use the i18next-http-backend module, let us install it first:

npm install i18next-http-backend

Once this is successful, the first step would be to import this package into the i18n.js file and then configure it:

i18n.js

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import Backend from 'i18next-http-backend';
i18n
.use(Backend)
.use(initReactI18next)
.init({
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json',
},
lng: 'en',
interpolation: {
escapeValue: false,
},
});

The next step would be to move the translations to the public folder with the following structure:

folder_structure.PNG

Each translation.json file should contain translations for a single language, for example:

en/translation.json

{
"welcome": {
"text": "Welcome to this React Internationalization App"
},
"interpolation_pluralization": {
"text_one": "There is only one Article on this",
"text_other": "There are {{count}} Articles on this"
},
"datetime": "Today is {{val, datetime}}"
}

Now when we load our app, it will still look the same, but your translations are now lazy-loaded on demand. The code is better organized; if we want to support a new language, we just need a new translation JSON file. Note: We can also have multiple translation files thanks to the namespaces feature of i18next.

#Managing and Loading Translations from Hygraph

Hygraph is a cutting-edge content management platform that enables teams to provide content to any channel. If this is your first time exploring Hygraph, create a free-forever developer account and begin your first project. You may also find some tips on how to integrate Hygraph in React.

Let's look at how we can simply translate, publish, and manage material with several locales from a single piece of content using Hygraph, which maintains and loads translations with GraphQL. The first step would be to establish a project, and then construct a schema for the project, being sure to check the box next to Localize fields while creating each field, as seen below.

hygraph_1.PNG

Once all fields have been created, the next step before you start inputting content would be to add the particular locales (languages) you want your application to support by going to settings → Locales → and then selecting the language as seen below:

hygraph_2.PNG

At this point, we can start input data into these fields, but we first need to enable the particular languages we want on the right side so a field can be created for them

hygraph_3.PNG

Editor's Note

You can read more on how to handle localization in Hygraph here

Loading Translations from Hygraph

Once you are done inputting all your content, you can publish. Let’s now see how to load those translations via their languages. In Hygraph querying is done with graphql-request and for us to do that in React, we first need to install the dependency by running the command below:

npm i graphql-request

Once it has successfully installed, the next step would be to import it into our App.js file, so we can now query the endpoint from Hygraph:

import { request } from 'graphql-request';

Querying with GraphQL

Let’s now see various ways we can query our endpoint, we can set a default locale (via its code) and a fallback in case the particular language is not available by passing in the (locales: [en, de]) parameter:

{
products(locales: [en, fr]) {
id
title
description
}
}

This will give us our output in English since we have our content in English, but suppose there is no content found for en, it will then fetch content in fr. Here is the output:

{
"data": {
"products": [
{
"id": "cl0xocls20r3k0bmp2hfhb0ey",
"title": "Here is a flower",
"description": "This is a very beautiful flower, many people will love"
}
]
}
}

We can also get data for a particular language by entering that locale, as seen below:

hygraph_4.PNG

Finally, the last step would be to load our translations into our react application using graphql-request:

const fetchProducts = async () => {
const { products } = await request(
'https://api-eu-west-2.hygraph.com/v2/cl0xn4yvn3iq501xm93s418jo/master',
`{
products (locales: [fr]) {
id
title
description
}
}`
);
};

#Conclusion

In this guide, we learned about internationalization, and how to use i18next in a React application. We saw different features of internationalization like translation, interpolation, pluralization, date/time translations, lazy loading translation files, and finally wrapped up with Hygraph integration.

Blog Author

Joel Olawanle

Joel Olawanle

Joel Olawanle is a Frontend Engineer and Technical writer based in Nigeria who is interested in making the web accessible to everyone by always looking for ways to give back to the tech community. He has a love for community building and open source.

Share with others

Sign up for our newsletter!

Be the first to know about releases and industry news and insights.