Complete Guide to Internationalization in React using React i18n

Muhammed cuma
5 min readMar 5, 2023

React is a popular front-end JavaScript library that has gained a lot of popularity in recent years. With the rise of globalization and the need for websites to support multiple languages, React i18n has become an essential tool for developers. React i18n allows developers to easily add multi-language support to their applications.

In this article, we will explore how to initialize React i18n, add languages, get languages from JSON files, get languages from an API, change language, cache language in cookies, structure files inside the project, and update translations.

Initializing React i18n

Before you can start using React i18n, you must initialize it. This involves creating an instance of the i18n object and configuring it with the appropriate settings. Here’s an example of how to do this:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
i18n
.use(initReactI18next)
.init({
lng: 'en',
fallbackLng: 'en',
keySeparator: false,
interpolation: {
escapeValue: false,
},
});

In this example, we are using the i18next and react-i18next packages to initialize React i18n. We set the default language to en and set the fallback language to en as well. The keySeparator option is set to false because we want to use the full string as the translation key. Finally, we configure the interpolation to not escape any values.

Adding Languages

Once React i18n is initialized, you can start adding languages to your application. You can add as many languages as you want by creating a new JSON file for each language. Here’s an example of how to add a language file:

{
"welcome": "Welcome to my website!",
"description": "This is a demo website to show how to use React i18n."
}

In this example, we have added an English language file with two translations: welcome and description.

Getting Languages from JSON Files

To get languages from JSON files, you can use the i18next-http-backend package. This package allows you to load language files from a remote server or a local file. Here's an example of how to get languages from a JSON file:

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

In this example, we are using the i18next-http-backend package to load language files from a local file. The loadPath option tells i18next where to load the language files from. The {{lng}} placeholder is replaced with the current language code, and the {{ns}} placeholder is replaced with the namespace (defaults to translation).

Caching Language in Cookies

To make sure that the user’s language preference is persisted across sessions, you can cache the language in a cookie. Here’s an example of how to cache the language in a cookie:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import HttpBackend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
import Cookies from 'js-cookie';
const languageDetector = new LanguageDetector();
languageDetector.addDetector({
name: 'cookie',
lookup(options) {
return Cookies.get('lang');
},
});
i18n
.use(HttpBackend)
.use(languageDetector)
.use(initReactI18next)
.init({
fallbackLng: 'en',
keySeparator: false,
interpolation: {
escapeValue: false,
},
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json',
},
});
function handleChangeLanguage(event) {
const newLang = event.target.value;
Cookies.set('lang', newLang);
i18n.changeLanguage(newLang);
}
<select onChange={handleChangeLanguage}>
<option value="en">English</option>
<option value="fr">Français</option>
<option value="es">Español</option>
</select>

In this example, we use the js-cookie package to set and get the language preference from a cookie. We also use the i18next-browser-languagedetector package to detect the user's language preference from the cookie.

Structuring Files Inside the Project

When adding multiple languages to your application, it’s important to structure the language files in a way that makes sense. One common approach is to organize the language files by language code and namespace. Here’s an example of how to structure the language files inside the project:

locales/
en/
common.json
home.json
fr/
common.json
home.json
es/
common.json
home.json

In this example, we have a locales directory that contains a subdirectory for each language code. Inside each language directory, we have a JSON file for each namespace. The common.json file contains translations that are shared across the entire application, while the home.json file contains translations specific to the home page.

Updating Translations

Finally, it’s important to keep the translations up to date as the application evolves. You can use a translation management tool like Crowdin or Lokalise to manage your translations and collaborate with translators. Here’s an example of how to update the translations in React i18n:

import i18n from 'i18next';
function updateTranslations() {
i18n.reloadResources('en', 'common', () => {
console.log('Translations updated');
});
}
<button onClick={updateTranslations}>Update Translations</button>

In this example, we create an updateTranslations function that calls the reloadResources method of the i18n object. This method reloads the specified language and namespace from the backend and updates the translations. You can use this method to trigger an update whenever new translations are added or existing translations are modified.

Remember that adding internationalization support is an ongoing process that requires continuous effort and collaboration. Be sure to involve translators and users in the process and use tools like Crowdin or Lokalise to manage your translations. With a little bit of effort, you can make your application truly global and reach users in every corner of the world.

Getting Languages from an API

In addition to loading languages from JSON files, you can also load languages from an API. Here’s an example of how to load languages from an API using the i18next-http-backend package:

import i18n from 'i18next';
import HttpBackend from 'i18next-http-backend';
i18n
.use(HttpBackend)
.init({
backend: {
loadPath: '/api/translations/{{lng}}/{{ns}}',
},
fallbackLng: 'en',
debug: true,
});

In this example, we use the i18next-http-backend package to load the translations from an API endpoint /api/translations/{{lng}}/{{ns}}. The {{lng}} placeholder is replaced with the language code, and the {{ns}} placeholder is replaced with the namespace. You can customize the API endpoint to suit your needs.

By default, the i18next-http-backend package uses the GET HTTP method to fetch translations. If your API requires a different HTTP method or authentication, you can customize the options using the backend property of the i18n.init method.

Note that loading translations from an API can add latency and slow down the initial rendering of the application. To mitigate this, you can use caching and lazy loading techniques to load translations on demand.

Conclusion

In this article, we have covered the basics of using React i18n to add internationalization support to your React application. We have looked at how to initialize the i18n object, add languages, get languages from JSON files and APIs, change the language, cache the language in cookies, structure the files inside the project, and update the translations. By following these best practices, you can make your application accessible to users around the world and provide a seamless experience in their preferred language.

Remember that adding internationalization support is an ongoing process that requires continuous effort and collaboration. Be sure to involve translators and users in the process and use tools like Crowdin or Lokalise to manage your translations. With a little bit of effort, you can make your application truly global and reach users in every corner of the world.

--

--

Muhammed cuma

Passionate front-end developer with 5+ years of experience creating high-quality, responsive web applications. Skilled in React, Redux, and SOLID principles.