Skip to main content

React and i18next

This is a simple example of how to use this tool with i18next in React.

Note that you can also use any other i18n library or framework of your choice.

Let's start by installing all the necessary dependencies.

npm i i18next react-i18next
npm i i18n-collector --save-dev

Let's take a closer look at each of these dependencies.

  • i18next is a core library for i18n.
  • react-i18next is a library for using i18next with React.
  • i18n-collector is a tool that simplifies the management of multiple translation files in your application.

1. Configure i18next

Let's assume that our app needs to support two languages: 🇬🇧 English and 🇩🇪 German.

/src/i18n.js

import i18n from "i18next";
import en from "./locales/en.json";
import de from "./locales/de.json";

i18n.use(initReactI18next).init({
resources: {
en,
de,
},
lng: "en",
fallbackLng: "en",
interpolation: {
escapeValue: false,
},
});

We've created a configuration file for i18next and imported ./locales/en.json and ./locales/de.json files. These files will be generated by i18n-collector later, and it is important that you do not create them manually.

info

The configuration we've provided for i18next is a simple one that may not meet all of your needs. You may need to configure i18next differently depending on your specific requirements. For more information about i18next configuration options, please refer to the official i18next documentation.

2. Add new scripts to package.json

{
"scripts": {
"i18n:compile": "npx i18n-collector run locales --input src --clear",
"i18n:watch": "npx i18n-collector run locales --input src --clear --watch"
}
}

Let's take a closer look at each of these scripts.

  • i18n:compile - compiles translation files into the ./locales directory
  • i18n:watch - compiles translation files and watches for changes (useful for development).

3. Add ./locales to your .gitignore file.

If you are working with a team, it is recommended that you do not commit your compiled translation files to the repository, as they can lead to merge conflicts.

.gitignore

# other files
locales

4. Create a new component

Let's say we need to create a Product component to display a product card. To get started, let's create a directory for our component and add a file for its translations

src
└── components
└── Product
├── Product.jsx
└── Product.locale.json

As you can see, we've created a Product.locale.json file next to our Product.jsx file. This file will contain translations for our Product component.

Now, let's prepare some translations for our Product component.

/src/components/Product/Product.locale.json

{
"en": {
"name": "Product name",
"description": "Description",
"price": "Price",
"buy": "Add to cart"
},
"de": {
"name": "Produktname",
"description": "Beschreibung",
"price": "Preis",
"buy": "In den Warenkorb"
}
}

Let's write our component.

/src/components/Product/Product.jsx

import { useTranslation } from "react-i18next";

export default function Product({ product }) {
const { t } = useTranslation();

return (
<div>
<h1>
{t("Product:name")}: {product.name}
</h1>
<img src={product.image} alt={product.name} />
<p>
{t("Product:description")}: {product.description}
</p>
<p>
{t("Product:price")}: {product.price}
</p>
<button>{t("Product:buy")}</button>
</div>
);
}

As you can see, we've used the useTranslation hook with our Product namespace to access the translations for our component.

warning

Note that you shouldn't import the Product.locale.json file anywhere. It'll be found and handled automatically by i18n-collector.

5. Compile translations files

We've created a component and added translations for it. Now we can use the i18n:compile script to compile our translations files.

npm run i18n:compile

As a result, we now have two files in the ./locales directory that were generated by the above script.

locales
├── en.json
└── de.json

Let's take a look at the en.json file.

/locales/en.json

{
"Product": {
"name": "Product name",
"description": "Description",
"price": "Price",
"buy": "Add to cart"
}
}

Note that it is important to use the correct locale keys when using the useTranslation hook in the React components, as they will match the keys defined in the translation files.

For example, if we have a key description defined in the Product.locale.json file, we will need to use the same key in the component when calling the t function, like t('Product:productTitle'). The Product: prefix (namespace) is added automatically by i18n-collector based on the name of the file.

info

You can use the --watch flag to automatically recompile your translation files when you make changes to them.

6. ⚡️ Add TypeScript

You can essentially improve your development experience by using TypeScript with i18next and i18n-collector.

i18n-collector will collect all your translations and generate a single file for each language and i18next can use these files to infer types for all your translations.

Let's use official i18next TypeScript example as a base.

i18n.ts

import "i18next";
import en from "./locales/en.json"; // import compiled file

// extend i18next's module declaration
declare module "i18next" {
interface CustomTypeOptions {
resources: {
[key in keyof typeof en]: (typeof en)[key];
};
}
}

// configure i18next

Now TypeScript will check your usage of t function and will show you an error if you use a wrong namespace or key.

<button>{t("Product:buy")}</button> // ✅ correct
<button>{t("WrongNamespace:buy")}</button> // ❌ incorrect