Adding Multi-Lingual Support in React

Published: (January 18, 2026 at 02:14 AM EST)
4 min read
Source: Dev.to

Source: Dev.to

To add multi‑language support to a React project we’ll use react‑i18next, which is built on top of i18next.
The library provides components that automatically render translated content when the language changes and can be used with any UI framework (Angular, Vue, etc.).

Documentation:

1. Install the required packages

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

2. Create the i18n configuration file

Create a file named i18n.js in the src folder and paste the following code:

// src/i18n.js
import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import Backend from "i18next-xhr-backend";
import { initReactI18next } from "react-i18next";

const fallbackLng = ["en"]; // default language

i18n
  .use(Backend)               // loads translation files
  .use(LanguageDetector)       // detects the user language
  .use(initReactI18next)       // passes i18n instance to react-i18next
  .init({
    fallbackLng,
    detection: {
      checkWhitelist: true,
    },
    debug: false,
    interpolation: {
      escapeValue: false, // React already escapes values
    },
    // If you store translations somewhere else, configure the path here:
    // backend: {
    //   loadPath: "/assets/locale/{{lng}}/translation.json",
    // },
  });

export default i18n;

Note: In App.js (or the root component) import the configuration so it runs once:

import "./i18n";

3. Folder structure for translation files

public/
└─ locale/
   ├─ en/
   │  └─ translation.json
   └─ fr/
      └─ translation.json

public/locale/en/translation.json

{
  "hello": "Hello",
  "cancel": "Cancel",
  "continue": "Continue"
}

public/locale/fr/translation.json

{
  "hello": "Salut",
  "cancel": "Annuler",
  "continue": "Continuez"
}

If you prefer a different location (e.g., assets/locale), adjust the backend.loadPath option in i18n.js:

backend: {
  loadPath: "/assets/locale/{{lng}}/translation.json",
},

4. Using translations in components

The useTranslation hook gives you:

  • t – a function to retrieve a translation by its key.
  • i18n – the i18next instance, which provides changeLanguage().

Example: Language selector component

// src/components/LanguageSelector.tsx
import { Fragment } from "react";
import { Menu, Transition } from "@headlessui/react";
import { GlobeAltIcon } from "@heroicons/react/24/outline";
import { useTranslation } from "react-i18next";

function classNames(...classes: string[]) {
  return classes.filter(Boolean).join(" ");
}

const countries = [
  { code: "fr", name: "Français", country_code: "fr" },
  { code: "en", name: "English", country_code: "gb" },
];

export const LanguageSelector = () => {
  const { t, i18n } = useTranslation();

  return (
    <Menu as="div" className="relative inline-block text-left">
      {/* ... UI markup ... */}
      {countries.map((lng) => (
        <Menu.Item key={lng.code}>
          {({ active }) => (
            <button
              className={classNames(
                active ? "bg-gray-100" : "",
                "block w-full text-left px-4 py-2 text-sm"
              )}
              onClick={() => i18n.changeLanguage(lng.code)}
            >
              {/* You could add a flag icon using lng.country_code here */}
              {lng.name}
            </button>
          )}
        </Menu.Item>
      ))}
    </Menu>
  );
};

Now you can use the t function anywhere in your UI:

import { useTranslation } from "react-i18next";

export const Greeting = () => {
  const { t } = useTranslation();

  return <h1>{t("hello")}!</h1>;
};

Switching the language via the selector will instantly re‑render all components that use t.

5. Recap

  1. Install i18next, react‑i18next, and the helper plugins.
  2. Initialise i18next in i18n.js and import it once (e.g., in App.js).
  3. Store translation files under public/locale/<lng>/translation.json.
  4. Use useTranslation to fetch translations (t) and change the language (i18n.changeLanguage).

You now have a fully functional, multi‑language React application! 🚀

Language Selector Component (alternative implementation)

import { Menu, Transition } from "@headlessui/react";
import { Fragment } from "react";
import { useTranslation } from "react-i18next";

const LanguageSelector = () => {
  const { i18n } = useTranslation();

  const languages = [
    { code: "en", name: "English", country_code: "gb" },
    { code: "fr", name: "Français", country_code: "fr" },
    // add more languages as needed
  ];

  return (
    <>
      <Menu as="div" className="relative inline-block text-left">
        {/* ... UI markup ... */}
        {languages.map((lng) => (
          <Menu.Item key={lng.code}>
            {({ active }) => (
              <button
                className={active ? "bg-gray-100" : ""}
                onClick={() => i18n.changeLanguage(lng.code)}
                disabled={i18n.language === lng.code}
              >
                {lng.name}
              </button>
            )}
          </Menu.Item>
        ))}
      </Menu>
    </>
  );
};

export default LanguageSelector;

How It Works

The dropdown displays language options together with their country flags. When a user selects a language, i18n.changeLanguage(languageCode) is called, updating the language across the entire application.

Language selector dropdown

Sample Form Component

Below is a simple component that renders localized labels using the t function from react‑i18next.

import ModuleContainer from "components/shared/moduleContainer/ModuleContainer";
import { useTranslation } from "react-i18next";

function SampleForm() {
  const { t } = useTranslation();

  return (
    <ModuleContainer>
      <label>{t("hello")}</label>
      <button>{t("cancel")}</button>
    </ModuleContainer>
  );
}

export default SampleForm;

Sample form with translations

Another view of the translated form

When a language is selected via the LanguageSelector, the t function automatically returns the appropriate translation for each key ("hello", "cancel", etc.). This approach lets you render labels and messages in any supported language throughout your React application.

If you found this helpful, feel free to subscribe, clap, like, and share. Cheers!

Back to Blog

Related posts

Read more »

Fundamentals of react app

Introduction Today we’re going to look at the reasons and uses of the files and folders that are visible when creating a React app. !React app structurehttps:/...

React Coding Challenge : TypeHead

Zeeshan Ali !ZeeshanAli-0704https://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws...