Ask your question and get a summary of the document by referencing this page and the AI provider of your choice
By integrating the Intlayer MCP Server to your favourite AI assistant can retrieve all the doc directly from ChatGPT, DeepSeek, Cursor, VSCode, etc.
See MCP Server docIf you have an idea for improving this documentation, please feel free to contribute by submitting a pull request on GitHub.
GitHub link to the documentationCopy doc Markdown to clipboard
React Internationalization (i18n) with react-i18next and Intlayer
Overview
- Intlayer helps you manage translations via component-level content declaration files.
- react-i18next is a popular React integration for i18next that provides hooks like useTranslation to fetch localized strings in your components.
When combined, Intlayer can export dictionaries in i18next-compatible JSON so that react-i18next can consume them at runtime.
Why Use Intlayer with react-i18next?
Intlayer content declaration files offer a better developer experience because they are:
Flexible in File Placement
Put each content declaration file right next to the component that needs it. This structure allows you to keep translations co-located, preventing orphaned translations when components move or get deleted.bashCopy codeCopy the code to the clipboard
.└── src └── components └── MyComponent ├── index.content.ts # Content declaration file └── index.tsx
Centralized Translations
A single content declaration file collects all necessary translations for a component, making missing translations easier to catch.
With TypeScript, you even get compile-time errors if translations are missing.
Installation
In a Create React App project, install these dependencies:
Copy the code to the clipboard
# With npmnpm install intlayer react-i18next i18next i18next-resources-to-backend
Copy the code to the clipboard
# With yarnyarn add intlayer react-i18next i18next i18next-resources-to-backend
Copy the code to the clipboard
# With pnpmpnpm add intlayer react-i18next i18next i18next-resources-to-backend
What Are These Packages?
- intlayer – The CLI and core library for managing i18n configurations, content declarations, and building dictionary outputs.
- react-intlayer – React-specific integration for Intlayer, providing notably some script to automate the build of dictionaries.
- react-i18next – React-specific integration library for i18next, including the useTranslation hook.
- i18next – The underlying framework for translation handling.
- i18next-resources-to-backend – An i18next backend that dynamically imports JSON resources.
Configuring Intlayer to Export i18next Dictionaries
Create (or update) your intlayer.config.ts in the root of your project:
Copy the code to the clipboard
import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = { internationalization: { // Add as many locales as you wish locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH], defaultLocale: Locales.ENGLISH, }, content: { // Tell Intlayer to create i18next-compatible JSON dictionaryOutput: ["i18next"], // Choose an output directory for the generated resources // This folder will be created if it doesn't exist yet. i18nextResourcesDir: "./i18next/resources", },};export default config;
Note: If you’re not using TypeScript, you can create this config file as .cjs, .mjs, or .js (see the Intlayer docs for details).
Building the i18next Resources
Once your content declarations are in place (next section), run the Intlayer build command:
Copy the code to the clipboard
# With npmnpx run intlayer build
Copy the code to the clipboard
# With yarnyarn intlayer build
Copy the code to the clipboard
# With pnpmpnpm intlayer build
This will generate your i18next resources inside the ./i18next/resources directory by default.
A typical output might look like this:
Copy the code to the clipboard
.└── i18next └── resources ├── en │ └── my-content.json ├── fr │ └── my-content.json └── es └── my-content.json
Where each Intlayer declaration key is used as an i18next namespace (e.g., my-content.json).
Importing Dictionaries into Your react-i18next Configuration
To dynamically load these resources at runtime, use i18next-resources-to-backend. For instance, create an i18n.ts (or .js) file in your project:
Copy the code to the clipboard
import i18next from "i18next";import { initReactI18next } from "react-i18next";import resourcesToBackend from "i18next-resources-to-backend";i18next // react-i18next plugin .use(initReactI18next) // dynamically load resources .use( resourcesToBackend((language: string, namespace: string) => { // Adjust the import path to your resources directory return import(`../i18next/resources/${language}/${namespace}.json`); }) ) // Initialize i18next .init({ // Fallback locale fallbackLng: "en", // You can add other i18next config options here, see: // https://www.i18next.com/overview/configuration-options });export default i18next;
Copy the code to the clipboard
import i18next from "i18next";import { initReactI18next } from "react-i18next";import resourcesToBackend from "i18next-resources-to-backend";i18next .use(initReactI18next) .use( resourcesToBackend( (language, namespace) => import(`../i18next/resources/${language}/${namespace}.json`) ) ) .init({ fallbackLng: "en", });export default i18next;
Then, in your root or index file (e.g., src/index.tsx), import this i18n setup before rendering the App:
Copy the code to the clipboard
import React from "react";import ReactDOM from "react-dom/client";// Initialize i18n before anything elseimport "./i18n";import App from "./App";ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( <React.StrictMode> <App /> </React.StrictMode>);
Creating and Managing Your Dictionarys
Intlayer extracts translations from “content declaration files” located anywhere under ./src (by default).
Here’s a minimal example in TypeScript:
Copy the code to the clipboard
import { t, type Dictionary } from "intlayer";const content = { // The "key" will be your i18next namespace (e.g., "my-component") key: "my-component", content: { // Each "t" call is a separate translation node heading: t({ en: "Hello World", fr: "Bonjour le monde", es: "Hola Mundo", }), description: t({ en: "My i18n description text...", fr: "Ma description en i18n...", es: "Mi descripción en i18n...", }), },} satisfies Dictionary;export default content;
If you prefer JSON, .cjs, or .mjs, refer to the Intlayer docs.
By default, valid content declarations match the file extension pattern:
*.content.{ts,tsx,js,jsx,mjs,mjx,cjs,cjx,json}
Using the Translations in React Components
After you’ve built your Intlayer resources and configured react-i18next, you can directly use the useTranslation hook from react-i18next.
For instance:
Copy the code to the clipboard
import type { FC } from "react";import { useTranslation } from "react-i18next";/** * The i18next "namespace" is the Intlayer `key` from "MyComponent.content.ts" * so we'll pass "my-component" to useTranslation(). */const MyComponent: FC = () => { const { t } = useTranslation("my-component"); return ( <div> <h1>{t("heading")}</h1> <p>{t("description")}</p> </div> );};export default MyComponent;
Note that the t function references keys inside your generated JSON. For an Intlayer content entry named heading, you’ll use t("heading").
Optional: Integrate with Create React App Scripts (CRACO)
react-intlayer provides a CRACO-based approach for custom builds and dev server configuration. If you want Intlayer’s build step integrated seamlessly, you can:
- Install react-intlayer (if you haven’t): bash npm install react-intlayer --save-dev
Adjust your package.json scripts to use react-intlayer scripts:
jsoncCopy codeCopy the code to the clipboard
"scripts": { "start": "react-intlayer start", "build": "react-intlayer build", "transpile": "intlayer build"}
react-intlayer scripts are based on CRACO. You can also implement your own setup based on the intlayer craco plugin. See example here.
Now, running npm run build, yarn build, or pnpm build triggers both Intlayer and CRA builds.
TypeScript Configuration
Intlayer provides autogenerated type definitions for your content. To ensure TypeScript picks them up, add types (or types if you configured differently) to your tsconfig.json include array:
Copy the code to the clipboard
{ "compilerOptions": { // ... }, "include": ["src", "types"],}
This will let TypeScript infer the shape of your translations for better autocompletion and error detection.
Git Configuration
It is recommended to ignore auto-generated files and folders from Intlayer. Add this line to your .gitignore:
Copy the code to the clipboard
# Ignore the files generated by Intlayer.intlayeri18next
You typically do not commit these resources or .intlayer internal build artifacts, as they can be regenerated on each build.