Building a Multilingual React App with i18n

Omer Faruk CAPUR
5 min readMay 22, 2024

--

Hi my dear readers! Today, we’ll use react-i18next to create a multilingual React application in this article. We’ll cover how to set up i18n, control translations using a custom translations.js file, and dynamically switch between languages. You should have no trouble implementing internationalization in your React projects by the end of this guide.

1.An Overview of React i18n

For your program to be usable by users in a variety of languages and geographical locations, localization (l10n) and internationalization (i18n) are important. React and i18next may be easily integrated thanks to the react-i18next package, which also offers robust translation management features.

2.Configuring the Project for React

First, let’s create a brand-new React project. Launch your terminal and type:

npx create-react-app react-i18n-internalization
cd react-i18n-internalization

NOTE = After this stage, it would be beneficial to delete the files and code blocks that are not useful to us. I created a starter-kit for you. You can access it from this link (https://github.com/omrfrkcpr/react-i18n-internationalization/tree/main/starter-kit).

You can obtain the starter-kit in your own locale by clone or copy-paste. If you cloned, there will be no node_modules. Therefore, first run the following commands in the relevant terminal.

npm install
npm start

If you copy the code blocks from the starter-kit, node_modules is already downloaded in your project. In this case, you can just run the following command.

npm start

We should now be able to see the live version of our project at http://localhost:3000/. A page like this should greet us.

3.Installing Required Dependencies

Next, we need to install the necessary dependencies:

npm install i18next react-i18next i18next-http-backend i18next-browser-languagedetector

These packages will help us manage translations, detect the user’s language, and load language files.

NOTE = After installation these packages, we have to stop running project with using CTRL + Ccommand, and start again with using npm startcommand.

4. Configuring i18next

For i18n configuration, we will first create a new directory called i18nin the src directory. After that, create a new file called i18n.js in the i18n directory to configure i18next:

// src/i18n/i18n.js
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import enTranslation from "../locales/en/en.json";
import deTranslation from "../locales/de/de.json";

const resources = {
en: {
translation: enTranslation,
},
de: {
translation: deTranslation,
},
};

const lng = localStorage.getItem("i18nextLng") || "en"; // If there is a language saved in local storage, we prefer it first. Otherwise, we want it to have English value as default.

i18n
.use(initReactI18next)
.init({
lng,
resources,
})
.then(() => {
localStorage.setItem("i18nextLng", i18n.language);
});

export default i18n;

This configuration uses HttpApi to load translation files, LanguageDetector to detect the user's language preference, and initReactI18next to integrate i18next with React.

5. Creating a Custom Translations File

Instead of directly using common text keys in our components, we’ll manage them through a custom translations.js file. First create a new directory called localesin the src directory. Then, create translations.js in the locales directory:

// src/locales/translations.js
const translations = {
header: "welcome",
paragraph: "description",
};

export default translations;

By storing our translation keys in this file, we may improve the readability and maintainability of our code.

6. Importing i18n Configuration

Update src/index.js to import the i18n configuration:

// src/index.js
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import "./i18n"; // Import i18n configuration

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

Now, update src/App.js to use the custom translations file and implement a language switcher:

// src/App.js
import "./App.css";
import React from "react";
import { useTranslation } from "react-i18next";
import translations from "./locales/translations";

function App() {
const { t, i18n } = useTranslation();

const changeLanguage = (lng) => {
i18n.changeLanguage(lng);
localStorage.setItem("i18nextLng", lng); // Save our value to local storage so that it remains in the selected language in which we refreshed the page.
};

return (
<div className="App">
<header className="App-header">
<h1>{t(translations.header)}</h1>
<p>{t(translations.paragraph)}</p>
<button onClick={() => changeLanguage("en")}>English</button>
<button onClick={() => changeLanguage("de")}>Deutsch</button>
</header>
</div>
);
}

export default App;

7.Creating Translation Files

Create the translation files in the public/locales directory.

  • English Translation (src/locales/en/en.json)
{
"welcome": "Welcome to my article about React Internationalization",
"description": "This is a simple example of react-i18next"
}
  • German Translation (src/locales/de/de.json)
{
"welcome": "Willkommen zu meinem Artikel über React Internationalization",
"description": "Dies ist ein einfaches Beispiel für react-i18next"
}

NOTE = In the common.json file, we write the keys and values that we expect to be the same in both languages. If we want different texts to be created depending on the language, we need to open an extra file for this.

8. Pros and Cons of Using a Custom Translations File

Pros:

  • Organization: Keeping translation keys in a single file (translations.js) makes your code cleaner and more organized.
  • Maintainability: Easier to manage and update translation keys in one central location.
  • Readability: Improves readability of your components by abstracting translation keys.

Cons:

  • Additional Layer: Adds an extra layer of indirection, which might be unnecessary for smaller projects.
  • Sync Issues: Risk of translation keys in translations.js becoming out of sync with actual translations if not managed properly.

9. Conclusion

By following this guide, you’ve learned how to implement localization in your React applications using react-i18next and a custom translations.js file. This approach not only makes your code more organized and maintainable but also prepares your app for a global audience. Remember to regularly update and manage your translation files to keep everything in sync.

You can also access the finished final repo here to obtain the final codes or check your codes. (https://github.com/omrfrkcpr/react-i18n-internationalization/tree/main/final-kit)

Thank you for spending your valuable time and reading my article. I hope you were able to find answers to the questions in your minds.

--

--