# Introduction

{% hint style="success" %}
🚀 New: **Locize** is now **Free** for small projects!\
We've replaced the trial-only model with a **Free plan**.\
Manage up to 2,000 words and 100,000 downloads for $0/mo.\
⇒ [Check it out!](https://www.locize.com/pricing?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme)
{% endhint %}

{% hint style="info" %}
🎉 Announcing [`i18next-cli`](https://github.com/i18next/i18next-cli):\
The New Official Toolkit for i18next.\
⇒ [Learn More](https://www.locize.com/blog/i18next-cli?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme)

{% embed url="<https://www.youtube.com/watch?v=aWZnZXwGg34>" %}
{% endhint %}

## What is react-i18next?

react-i18next is a powerful **internationalization** framework for [**React**](https://reactjs.org) / [**React Native**](https://reactnative.dev/) which is based on [**i18next**](https://www.i18next.com). Check out the [history of i18next](https://www.i18next.com/misc/the-history-of-i18next) and [when react-i18next was introduced](https://www.i18next.com/misc/the-history-of-i18next#v2).

{% hint style="info" %}
You should read the [i18next](https://www.i18next.com) documentation. The [configuration options](https://www.i18next.com/overview/configuration-options) and translation functionalities like [plurals](https://www.i18next.com/translation-function/plurals), [formatting](https://www.i18next.com/translation-function/formatting), [interpolation](https://www.i18next.com/translation-function/interpolation), ... are documented there.
{% endhint %}

The module provides multiple components eg. to assert that needed translations get loaded or that your content gets rendered when the language changes.

{% hint style="warning" %}
Managing JSON files manually?\
When your project grows, streamline your workflow with [locize](https://www.locize.com/i18next?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme), the official TMS built by the creators of i18next. [**Try it for free!**](https://www.locize.com/i18next?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme)
{% endhint %}

{% embed url="<https://www.youtube.com/watch?t=705s&v=SA_9i4TtxLQ>" %}

> **Official CLI**
>
> ⭐ [i18next-cli](https://github.com/i18next/i18next-cli)
>
> The official, high-performance, all-in-one command-line tool for i18next. It handles key extraction, code linting, locale syncing, and type generation. It's built with modern technologies for maximum speed and accuracy. This is the recommended tool for all i18next projects.

As react-i18next depends on [i18next](https://i18next.com) you can use it in any other UI framework and on the server-side (node.js, .net, ...) too. Like the React philosophy - just:

> **Learn once - translate everywhere**.

{% hint style="success" %}
Check out [this video](https://youtu.be/37rcHVcQ6t0) and the corresponding [blog post](https://www.locize.com/blog/how-to-easily-add-i18n-to-your-software?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme) about "Vite + React + TypeScript" with i18next.

<img src="/files/UA1gjWMAOTx5L2iId0PH" alt="" data-size="original">
{% endhint %}

{% hint style="success" %}
[Here](https://www.locize.com/blog/react-i18next/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme) you'll find a simple tutorial on how to best use react-i18next.\
Some basics of i18next and some cool possibilities on how to optimize your localization workflow.[\ <img src="/files/-MYGrwr09aHCLauHUHx9" alt="" data-size="original">](https://www.locize.com/blog/react-i18next/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme)
{% endhint %}

{% hint style="success" %}
**Who's using i18next?** At least **1,500+ of the world's top 100,000 websites** run on i18next — including many React apps built with react-i18next and next-i18next.\
⇒ [See who uses i18next](https://www.locize.com/blog/who-uses-i18next?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=who_uses_i18next)

[![](/files/E4ZXVW5quSxRXanJM7zx)](https://www.locize.com/blog/who-uses-i18next?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=who_uses_i18next)
{% endhint %}

{% hint style="info" %}
**Using Next.js?**\
Since [next-i18next v16](https://www.locize.com/blog/next-i18next-v16/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme), both App Router and Pages Router are supported in a single package — no boilerplate needed.\
[Here](https://www.locize.com/blog/next-i18next/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme) you'll find a blog post on how to best use [next-i18next](https://github.com/i18next/next-i18next) with client side translation download and SEO optimization.

[![](/files/sjfxTwvThpPoxIhZEX0O)](https://www.locize.com/blog/next-i18next/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme)
{% endhint %}

{% hint style="info" %}
**Using Remix?**\
[Here](https://github.com/locize/locize-remix-i18next-example) you'll find a simple example and [here a step by step tutorial](https://www.locize.com/blog/remix-i18n/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme) on how to best use remix-i18next.

[![](/files/yy5kBEi2hrvbFO8tWP2y)](https://www.locize.com/blog/remix-i18n/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme)
{% endhint %}

{% hint style="info" %}
**Using Gatsby?**\
[Here](https://github.com/locize/locize-gatsby-example) you can find an example and an appropriate [blog post](https://www.locize.com/blog/gatsby-i18n/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme).

[![](/files/iBmQJsLem8puRKYir5Z0)](https://www.locize.com/blog/gatsby-i18n/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme)
{% endhint %}

## What does my code look like

**Before:** Your React code would have looked something like:

```jsx
...
<div>Just simple content</div>
<div>
  Hello <strong title="this is your name">{name}</strong>, you have {count} unread message(s). <Link to="/msgs">Go to messages</Link>.
</div>
...
```

**After:** With the `Trans` component just change it to:

{% tabs %}
{% tab title="JavaScript" %}

```jsx
...
<div>{t('simpleContent')}</div>
<Trans i18nKey="userMessagesUnread" count={count}>
  Hello <strong title={t('nameTitle')}>{{name}}</strong>, you have {{count}} unread message(s). <Link to="/msgs">Go to messages</Link>.
</Trans>
...
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
...
<div>{t($ => $.simpleContent)}</div>
<Trans i18nKey="userMessagesUnread" count={count}>
  Hello <strong title={t($ => $.nameTitle)}>{{name}}</strong>, you have {{count}} unread message(s). <Link to="/msgs">Go to messages</Link>.
</Trans>
...
```

{% endtab %}
{% endtabs %}

If you prefer not using semantic keys but text - [that's also possible](https://www.i18next.com/principles/fallback.html#key-fallback).

## On top: [Localization as a service](https://www.locize.com/i18next?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme)

i18next supports translation management tools such as [Locize](https://www.locize.com/i18next?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme).

{% hint style="success" %}
[Here](https://github.com/locize/react-tutorial) you can find a step by step guide, which will unleash the full power of i18next in combination with locize.\
See how your developer experience with this localization workflow [could look like](https://youtu.be/osScyaGMVqo).\
There's also the possibility to have an [even more focused developer experience](https://youtu.be/VfxBpSXarlU), with the help of the [auto-machinetranslation workflow](https://www.locize.com/docs/automatic-translation?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme) and the use of the save missing keys functionality, new keys not only gets added to locize automatically, while developing the app, but are also [automatically translated](https://youtu.be/VfxBpSXarlU) into the target languages using machine translation (like [Google Translate](https://cloud.google.com/translate)).
{% endhint %}

{% embed url="<https://www.youtube.com/watch?v=lCuHSZvSiVg>" %}

[Learn more about the enterprise offering](https://www.i18next.com/overview/for-enterprises)

#### Manage your i18next translations directly from Claude and other AI assistants via the [Locize MCP server](https://www.locize.com/docs/integration/mcp?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=readme)

{% embed url="<https://youtu.be/G7bfVfyseaQ>" %}


# Getting started

## Installation

### Install using npm

react-i18next can be added to your project using **npm**:

```bash
# npm
$ npm install react-i18next i18next --save
```

In the `/dist` folder you find specific builds for `commonjs`, `es6 modules`,...

{% hint style="info" %}
The module is optimized to load by webpack, rollup, ... The correct entry points are already configured in the package.json. There should be no extra setup needed to get the best build option.
{% endhint %}

### Load from CDN

You can also add a script tag to load react-i18next from one of the CDNs providing it, eg.:

**unpkg.com**

* <https://unpkg.com/react-i18next/react-i18next.js>
* <https://unpkg.com/react-i18next/react-i18next.min.js>

## Translation "how to"

{% hint style="info" %}
You should read the [i18next](https://www.i18next.com) documentation at some point as we do not repeat all the [configuration options](https://www.i18next.com/overview/configuration-options) and translation functionalities like [plurals](https://www.i18next.com/translation-function/plurals), [formatting](https://www.i18next.com/translation-function/formatting), [interpolation](https://www.i18next.com/translation-function/interpolation), ... here.
{% endhint %}

> **Official CLI**
>
> ⭐ [i18next-cli](https://github.com/i18next/i18next-cli)
>
> The official, high-performance, all-in-one command-line tool for i18next. It handles key extraction, code linting, locale syncing, and type generation. It's built with modern technologies for maximum speed and accuracy. This is the recommended tool for all i18next projects.

**You have two options to translate your content:**

### Simple content

Simple content can easily be translated using the provided `t` function.

**Before:**

```jsx
<div>Just simple content</div>
```

**After:**

{% tabs %}
{% tab title="JavaScript" %}

```jsx
<div>{t('simpleContent')}</div>
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
<div>{t($ => $.simpleContent)}</div>
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
You will get the t function by using the [useTranslation](/latest/usetranslation-hook) hook or the [withTranslation](/latest/withtranslation-hoc) hoc.
{% endhint %}

### JSX tree

Sometimes you might want to include html formatting or components like links into your translations. (Always try to get the best result for your translators - the final string to translate should be a complete sentence).

**Before:** Your react code would have looked something like:

```jsx
<div>
  Hello <strong title="this is your name">{name}</strong>, you have {count} unread message(s). <Link to="/msgs">Go to messages</Link>.
</div>
```

**After:** With the trans component just change it to:

```jsx
<Trans i18nKey="userMessagesUnread" count={count}>
  Hello <strong title={t('nameTitle')}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
</Trans>
```

{% tabs %}
{% tab title="JavaScript" %}

```
<Trans i18nKey="userMessagesUnread" count={count}>
  Hello <strong title={t('nameTitle')}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
</Trans>
```

{% endtab %}

{% tab title="TypeScript" %}

```
<Trans i18nKey="userMessagesUnread" count={count}>
  Hello <strong title={t($ => $.nameTitle)}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
</Trans>
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Learn more about the Trans Component [here](/latest/trans-component)
{% endhint %}

## Basic sample

This basic sample tries to add i18n in a one file sample.

{% tabs %}
{% tab title="JavaScript" %}

```jsx
import React from "react";
import { createRoot } from 'react-dom/client';
import i18n from "i18next";
import { useTranslation, initReactI18next } from "react-i18next";

i18n
  .use(initReactI18next) // passes i18n down to react-i18next
  .init({
    // the translations
    // (tip move them in a JSON file and import them,
    // or even better, manage them via a UI: https://react.i18next.com/guides/multiple-translation-files#manage-your-translations-with-a-management-gui)
    resources: {
      en: {
        translation: {
          "Welcome to React": "Welcome to React and react-i18next"
        }
      }
    },
    lng: "en", // if you're using a language detector, do not define the lng option
    fallbackLng: "en",

    interpolation: {
      escapeValue: false // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
    }
  });

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

  return <h2>{t('Welcome to React')}</h2>;
}

// append app to dom
const root = createRoot(document.getElementById('root'));
root.render(
  <App />
);
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
import React from "react";
import { createRoot } from 'react-dom/client';
import i18n from "i18next";
import { useTranslation, initReactI18next } from "react-i18next";

i18n
  .use(initReactI18next) // passes i18n down to react-i18next
  .init({
    // the translations
    // (tip move them in a JSON file and import them,
    // or even better, manage them via a UI: https://react.i18next.com/guides/multiple-translation-files#manage-your-translations-with-a-management-gui)
    resources: {
      en: {
        translation: {
          "Welcome to React": "Welcome to React and react-i18next"
        }
      }
    },
    lng: "en", // if you're using a language detector, do not define the lng option
    fallbackLng: "en",

    interpolation: {
      escapeValue: false // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
    }
  });

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

  return <h2>{t($ => $['Welcome to React'])}</h2>;
}

// append app to dom
const root = createRoot(document.getElementById('root'));
root.render(
  <App />
);
```

{% endtab %}
{% endtabs %}

#### RESULT:

![Preview of content](/files/-LNezJM1SpwlcneJMmwJ)

{% hint style="info" %}
This sample while very simple does come with some [drawbacks](/guides/the-drawbacks-of-other-i18n-solutions) to getting the full potential from using react-i18next you should read the extended [step by step guide](/latest/using-with-hooks).
{% endhint %}

### Do you like to read a more complete step by step tutorial?

{% hint style="info" %}
[Here](https://www.locize.com/blog/react-i18next/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=getting_started) you'll find a simple tutorial on how to best use react-i18next.\
Some basics of i18next and some cool possibilities on how to optimize your localization workflow.[\ <img src="/files/-MYGrwr09aHCLauHUHx9" alt="" data-size="original">](https://www.locize.com/blog/react-i18next/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=getting_started)
{% endhint %}

{% hint style="success" %}
Don't have a [Locize](https://www.locize.com/i18next?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=getting_started) account yet?\
You can now sign up for a **Free plan** to test the integration in your development environment indefinitely.
{% endhint %}


# Drawbacks of other i18n solutions

Let's make the sample using our own base i18n framework [i18next](https://i18next.com). Like all other solutions, some come with [drawbacks](#the-drawbacks). These will be highlighted after samples.

## Using a pure javascript i18n framework

{% tabs %}
{% tab title="JavaScript" %}

```jsx
import React, { Component } from "react";
import { createRoot } from 'react-dom/client';
import i18n from "i18next";

// translation catalog
const resources = {
  en: {
    translation: {
      "welcome": "Welcome to React and react-i18next"
    }
  }
};

// initialize i18next with catalog and language to use
i18n.init({
  resources,
  lng: "en"
});

class App extends Component {
  render() {
    return <h2>{i18n.t('welcome')}</h2>;
  }
}

// append app to dom
const root = createRoot(document.getElementById('root'));
root.render(
  <App />
);
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
import React, { Component } from "react";
import { createRoot } from 'react-dom/client';
import i18n from "i18next";

// translation catalog
const resources = {
  en: {
    translation: {
      "welcome": "Welcome to React and react-i18next"
    }
  }
};

// initialize i18next with catalog and language to use
i18n.init({
  resources,
  lng: "en"
});

class App extends Component {
  render() {
    return <h2>{i18n.t($ => $.welcome)}</h2>;
  }
}

// append app to dom
const root = createRoot(document.getElementById('root'));
root.render(
  <App />
);
```

{% endtab %}
{% endtabs %}

## More react adapted "react-i18n"

The above is basically how every i18n framework for react works. The translations and language get set when initiated and a translation function is made available. You could easily extend this hiding the i18n.init inside a provider and pass down the function by context to another component to translate strings.

So let's make this more visible with some pseudo code:

```javascript
import React, { Component } from "react";
import { createRoot } from 'react-dom/client';
import { I18nProvider, FormattedString } from "i18nLib";

// import translation catalog
import resources from './catalog-en.json';

class App extends Component {
  render() {
    return <h2><FormattedString msg="welcome" /></h2>;
  }
}

// append app to dom
const root = createRoot(document.getElementById('root'));
root.render(
  <I18nProvider lng="en" resources={resources}>
    <App />,
  </I18nProvider>
);
```

## The drawbacks

Before we come to the drawbacks let's highlight some advantages of those solutions above - they are very simple to get started.

### Changing the language

Can you easily change the language? Get the translations in other language loaded? Does the language change trigger a rerender?

That's what the [withTranslation](/latest/withtranslation-hoc) higher order component or [useTranslation](/latest/usetranslation-hook) hook do!

### Scale and split your translations into multiple files

When your project gets bigger you do not only want code splitting but you also like to load translations on demand to avoid loading all translations upfront which would result in bad load times for your website.

With loading translations asynchronous there comes another problem - does your framework handle the pending state during loading translation?

That's what the [withTranslation](/latest/withtranslation-hoc) higher order component or [useTranslation](/latest/usetranslation-hook) hook do!

### Can you translate combined jsx nodes in one sentence

Let's take following content:

```javascript
<p>
  Hello <strong>{name}</strong>, you have 
  <Link to="/msgs">{count} unread message(s)</Link>.
</p>
```

In most frameworks you will end having to split this into multiple translation strings. But for your translators it would make sense to have this as one sentence to translate like eg.:

```
Hello <1>{name}</1>, you have <3>{count} unread message(s)</3>.
```

You can do this using the [Trans component](/latest/trans-component).


# Quick start

## Install needed dependencies

We expect you having an existing react application - if not give [Vite](https://vite.dev/guide/#scaffolding-your-first-vite-project) (`npm create vite@latest`) or similar a try.

Install both react-i18next and i18next packages:

```bash
npm install react-i18next i18next --save
```

Why do you need i18next package? i18next is the core that provides all translation functionality while react-i18next gives some extra power for using with react.

#### Do you directly want to see an example?

Check out this basic [react example](https://github.com/i18next/react-i18next/tree/master/example/react) with a [browser language-detector](https://github.com/i18next/i18next-browser-languageDetector) and a [http backend](https://github.com/i18next/i18next-http-backend) to load translations from.

#### Do you like to read a more complete step by step tutorial?

{% hint style="success" %}
[Here](https://www.locize.com/blog/react-i18next/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=guides_quick_start) you'll find a simple tutorial on how to best use react-i18next.\
Some basics of i18next and some cool possibilities on how to optimize your localization workflow.[\
![](/files/-MYGrwr09aHCLauHUHx9)](https://www.locize.com/blog/react-i18next/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=guides_quick_start)
{% endhint %}

## Configure i18next

Create a new file `i18n.js` beside your `index.js` containing following content:

```javascript
import i18n from "i18next";
import { initReactI18next } from "react-i18next";

// the translations
// (tip move them in a JSON file and import them,
// or even better, manage them separated from your code: https://react.i18next.com/guides/multiple-translation-files)
const resources = {
  en: {
    translation: {
      "Welcome to React": "Welcome to React and react-i18next"
    }
  },
  fr: {
    translation: {
      "Welcome to React": "Bienvenue à React et react-i18next"
    }
  }
};

i18n
  .use(initReactI18next) // passes i18n down to react-i18next
  .init({
    resources,
    lng: "en", // language to use, more information here: https://www.i18next.com/overview/configuration-options#languages-namespaces-resources
    // you can use the i18n.changeLanguage function to change the language manually: https://www.i18next.com/overview/api#changelanguage
    // if you're using a language detector, do not define the lng option

    interpolation: {
      escapeValue: false // react already safes from xss
    }
  });

  export default i18n;
```

{% hint style="info" %}
The file does not need to be named `i18n.js`, it can be any other filename. Just make sure you import it accordingly.
{% endhint %}

The interesting part here is by `i18n.use(initReactI18next)` we pass the i18n instance to react-i18next which will make it available for all the components via the context api.

Then import that in `index.js`:

```javascript
import React, { Component } from "react";
import { createRoot } from 'react-dom/client';
import './i18n';
import App from './App';

// append app to dom
const root = createRoot(document.getElementById('root'));
root.render(
  <App />
);
```

{% tabs %}
{% tab title="JavaScript" %}
{% hint style="info" %}
If you need to access the `t` function or the `i18next` instance from outside of a React component you can simply import your `./i18n.js` and use the exported i18next instance:

<pre><code><strong>import i18next from './i18n'
</strong>
i18next.t('my.key')
</code></pre>

\
Also read about this [here](https://www.locize.com/blog/how-to-use-i18next-t-outside-react-components?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=guides_quick_start) and [here](https://github.com/i18next/react-i18next/issues/1236#issuecomment-762039023).
{% endhint %}
{% endtab %}

{% tab title="TypeScript" %}
{% hint style="info" %}
If you need to access the `t` function or the `i18next` instance from outside of a React component you can simply import your `./i18n.js` and use the exported i18next instance:

<pre><code><strong>import i18next from './i18n'
</strong>
i18next.t($ => $.my.key)
</code></pre>

\
Also read about this [here](https://www.locize.com/blog/how-to-use-i18next-t-outside-react-components?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=guides_quick_start) and [here](https://github.com/i18next/react-i18next/issues/1236#issuecomment-762039023).
{% endhint %}
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**React Native:** the Hermes engine does not implement `Intl.PluralRules`, which i18next needs for plurals (mandatory since i18next v24). Add the 2-line [polyfill](https://github.com/eemeli/intl-pluralrules): `npm install intl-pluralrules` and `import 'intl-pluralrules'` before your i18next init.
{% endhint %}

## Translate your content

### Using the hook

Using the hook in functional components is one of the options you have.

The `t` function is the main function in i18next to translate content. Read the [documentation](https://www.i18next.com/translation-function/essentials) for all the options.

{% tabs %}
{% tab title="JavaScript" %}

```jsx
import React from 'react';

// the hook
import { useTranslation } from 'react-i18next';

function MyComponent () {
  const { t, i18n } = useTranslation();
  return <h1>{t('Welcome to React')}</h1>
}
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
import React from 'react';

// the hook
import { useTranslation } from 'react-i18next';

function MyComponent () {
  const { t, i18n } = useTranslation();
  return <h1>{t($ => $['Welcome to React'])}</h1>
}
```

{% endtab %}
{% endtabs %}

Learn more about the hook [useTranslation](/latest/usetranslation-hook).

### Using the HOC

Using higher order components is one of the most used method to extend existing components by passing additional props to them.

The `t` function is the main function in i18next to translate content. Read the [documentation](https://www.i18next.com/translation-function/essentials) for all the options.

{% tabs %}
{% tab title="JavaScript" %}

```jsx
import React from 'react';

// the hoc
import { withTranslation } from 'react-i18next';

function MyComponent ({ t }) {
  return <h1>{t('Welcome to React')}</h1>
}

export default withTranslation()(MyComponent);
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
import React from 'react';

// the hoc
import { withTranslation } from 'react-i18next';

function MyComponent ({ t }) {
  return <h1>{t($ => $['Welcome to React'])}</h1>
}

export default withTranslation()(MyComponent);
```

{% endtab %}
{% endtabs %}

Learn more about the higher order component [withTranslation](/latest/withtranslation-hoc).

### Using the render prop

The render prop enables you to use the `t` function inside your component.

{% tabs %}
{% tab title="JavaScript" %}

```jsx
import React from 'react';

// the render prop
import { Translation } from 'react-i18next';

export default function MyComponent () {
  return (
    <Translation>
      {
        t => <h1>{t('Welcome to React')}</h1>
      }
    </Translation>
  )
}
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
import React from 'react';

// the render prop
import { Translation } from 'react-i18next';

export default function MyComponent () {
  return (
    <Translation>
      {
        t => <h1>{t($ => $['Welcome to React'])}</h1>
      }
    </Translation>
  )
}
```

{% endtab %}
{% endtabs %}

Learn more about the render prop [Translation](/latest/translation-render-prop).

### Using the Trans component

The Trans component is the best way to translate a JSX tree in one translation. This enables you to eg. easily translate text containing a link component or formatting like `<strong>`.

```jsx
import React from 'react';
import { Trans } from 'react-i18next';

export default function MyComponent () {
  return <Trans><H1>Welcome to React</H1></Trans>
}

// the translation in this case should be
"<0>Welcome to React</0>": "<0>Welcome to React and react-i18next</0>"
```

Don't worry if you do not yet understand how the Trans component works in detail. Learn more about it [here](/latest/trans-component).

## Next steps

Depending on your learning style, you can now read the more in-depth [step by step](/latest/using-with-hooks) guide and learn how to load translations using xhr or how to change the language.

Prefer having code to checkout? Directly dive into our examples:

* [Example react](https://github.com/i18next/react-i18next/tree/master/example/react)

> **Would you like to visually check the progress state of your translations?**
>
> *Try* [*translation-check*](https://github.com/locize/translation-check)*, it shows an overview of your translations in a nice UI. Check which keys are not yet translated.*\
> [![](/files/-McU11WehFkeBR6Vvagy)](https://github.com/locize/translation-check)


# Multiple Translation Files

One of the advantages of react-i18next is based on i18next it supports the separation of translations into multiple files - which are called namespaces in i18next context -> as you're accessing keys from a namespace defining that as a prefix:

So while this takes the translation from the defined default namespace:

{% tabs %}
{% tab title="JavaScript" %}

```jsx
i18next.t('look.deep');
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
i18next.t($ => $.look.deep);
```

{% endtab %}
{% endtabs %}

This will lookup the key in a namespace (file) called common.json:

{% tabs %}
{% tab title="JavaScript" %}

```jsx
i18next.t('common:look.deep'); // not recommended with ns prefix when used in combination with natural language keys
// better use the ns option:
i18next.t('look.deep', { ns: 'common' })
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
i18next.t($ => $.look.deep, { ns: 'common' })
```

{% endtab %}
{% endtabs %}

In order to use multiple namespaces/translation files, you need to specify it when calling [`useTranslation`](https://react.i18next.com/latest/usetranslation-hook) :

```javascript
const { t } = useTranslation(['translation', 'common']);
```

[`withTranslation`](https://react.i18next.com/latest/withtranslation-hoc):

```javascript
withTranslation(['translation', 'common'])(MyComponent);
```

or [`Translation`](https://react.i18next.com/latest/translation-render-prop):

{% tabs %}
{% tab title="JavaScript" %}

```jsx
<Translation ns={['translation', 'common']}>
{
  (t) => <p>{t('look.deep', { ns: 'common' })}</p>
}
</Translation>
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
<Translation ns={['translation', 'common']}>
{
  (t) => <p>{t($ => $.look.deep, { ns: 'common' })}</p>
}
</Translation>
```

{% endtab %}
{% endtabs %}

## Separating translation files

In i18next you have a lot of options to add translations on init, in your code calling API methods or using one of the backend implementation. For a detailed write up check out the ["Add or load translation guide on i18next.com"](https://www.i18next.com/how-to/add-or-load-translations).

With react-i18next you can use any of the components passing down the `t` function to your components to load namespaces:

* [useTranslation (hook)](/latest/usetranslation-hook)
* [withTranslation (HOC)](/latest/withtranslation-hoc)
* [Translation (render prop)](/latest/translation-render-prop)

All take arguments to define which namespaces to load and will Suspense rendering until those got loaded.

So you do not need to load all translations upfront enabling you to create huge react based applications without slowing down loading of the first page cause all translations need to be loaded upfront (hello other i18n implementations).

## Manage your translations with a management GUI

### [**locize**](https://www.locize.com/i18next?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=guides_multiple_translation_files) is the perfect translation management tool for your [**i18next**](https://www.i18next.com) project

#### ➡️ [i18next](https://www.i18next.com/) + [locize](https://www.locize.com/i18next?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=guides_multiple_translation_files) = [true continuous localization](https://www.locize.com/how-it-works?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=guides_multiple_translation_files#continuouslocalization)

[Here](https://github.com/locize/react-tutorial) you can find a step by step guide, which will unleash the full power of i18next in combination with locize.\
See how your developer experience with this localization workflow [could look like](https://youtu.be/osScyaGMVqo).\
There's also the possibility to have an [even more focused developer experience](https://youtu.be/VfxBpSXarlU), with the help of the [auto-machinetranslation workflow](https://www.locize.com/docs/automatic-translation?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=guides_multiple_translation_files) and the use of the save missing keys functionality, new keys not only gets added to locize automatically, while developing the app, but are also [automatically translated](https://youtu.be/VfxBpSXarlU) into the target languages using machine translation (like [Google Translate](https://cloud.google.com/translate)).

{% embed url="<https://youtu.be/osScyaGMVqo>" %}

{% embed url="<https://youtu.be/VfxBpSXarlU>" %}


# Step by step guide

## Install needed dependencies

We expect you to have an existing react application supporting [hooks](https://reactjs.org/docs/hooks-intro.html) (at least v16.7.0-alpha of react and react-dom).

Install both react-i18next and i18next packages:

```bash
npm install react-i18next i18next --save

# if you'd like to detect user language and load translation
npm install i18next-http-backend i18next-browser-languagedetector --save
```

### Configure i18next

I18next is the core of the i18n functionality while react-i18next extends and glues it to react.

Create a new file `i18n.js` beside your `index.js` containing following content:

```javascript
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
// don't want to use this?
// have a look at the Quick start guide 
// for passing in lng and translations on init

i18n
  // load translation using http -> see /public/locales (i.e. https://github.com/i18next/react-i18next/tree/master/example/react/public/locales)
  // learn more: https://github.com/i18next/i18next-http-backend
  // want your translations to be loaded from a professional CDN? => https://github.com/locize/react-tutorial#step-2---use-the-locize-cdn
  .use(Backend)
  // detect user language
  // learn more: https://github.com/i18next/i18next-browser-languageDetector
  .use(LanguageDetector)
  // pass the i18n instance to react-i18next.
  .use(initReactI18next)
  // init i18next
  // for all options read: https://www.i18next.com/overview/configuration-options
  .init({
    fallbackLng: 'en',
    debug: true,

    interpolation: {
      escapeValue: false, // not needed for react as it escapes by default
    }
  });


export default i18n;
```

The interesting part here is by `i18n.use(initReactI18next)` we pass the i18n instance to react-i18next which will make it available for all the components.

Then import that in `index.js`:

```javascript
import React, { Component } from "react";
import { createRoot } from 'react-dom/client';
import App from './App';

// import i18n (needs to be bundled ;)) 
import './i18n';

const root = createRoot(document.getElementById('root'));
root.render(
  <App />
);
```

{% tabs %}
{% tab title="JavaScript" %}
{% hint style="info" %}
If you need to access the `t` function or the `i18next` instance from outside of a React component you can simply import your `./i18n.js` and use the exported i18next instance:

```
import i18next from './i18n'

i18next.t('my.key')
```

{% endhint %}
{% endtab %}

{% tab title="TypeScript" %}
{% hint style="info" %}
If you need to access the `t` function or the `i18next` instance from outside of a React component you can simply import your `./i18n.js` and use the exported i18next instance:

```
import i18next from './i18n'

i18next.t($ => $.my.key)
```

{% endhint %}
{% endtab %}
{% endtabs %}

### Translate your content

#### Using the useTranslation hook

You can use the hook inside your functional components like:

{% tabs %}
{% tab title="JavaScript" %}

```jsx
import React, { Suspense } from 'react';
import { useTranslation } from 'react-i18next';

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

  return <h1>{t('Welcome to React')}</h1>
}

// i18n translations might still be loaded by the http backend
// use react's Suspense
export default function App() {
  return (
    <Suspense fallback="loading">
      <MyComponent />
    </Suspense>
  );
}
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
import React, { Suspense } from 'react';
import { useTranslation } from 'react-i18next';

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

  return <h1>{t($ => $['Welcome to React'])}</h1>
}

// i18n translations might still be loaded by the http backend
// use react's Suspense
export default function App() {
  return (
    <Suspense fallback="loading">
      <MyComponent />
    </Suspense>
  );
}
```

{% endtab %}
{% endtabs %}

The useTranslation hook function takes one options argument. You can either pass in a namespace or an array of namespaces to load.

```javascript
const { t, i18n } = useTranslation('common');

const { t, i18n } = useTranslation(['page1', 'common']);
```

#### Translation Files

Create a new file `public/locales/<language_code>/translation.json` with the following sample content.

```
{
  "title": "Welcome to react using react-i18next",
  "description": {
    "part1": "To get started, edit <1>src/App.js</1> and save to reload.",
    "part2": "Switch language between english and german using buttons above."
  }
}
```

Files are plain JSON you can checkout the full sample [here](https://github.com/i18next/react-i18next/tree/master/example/react/public/locales).

{% hint style="info" %}
Please note the t function will be either bound to the default namespace defined on i18next init or to the first one passed in arguments.
{% endhint %}

{% content-ref url="/pages/-LYGLmq-OW\_D-AC5zbbk" %}
[Multiple Translation Files](/guides/multiple-translation-files)
{% endcontent-ref %}

#### Using the withTranslation HOC

There might be some legacy cases where you are still forced to use classes. Don't worry, we still provide a hoc to cover these cases:

{% tabs %}
{% tab title="JavaScript" %}

```jsx
import React, { Component, Suspense } from 'react';
import { withTranslation } from 'react-i18next';

class LegacyComponentClass extends Component {
  render() {
    const { t } = this.props;

    return (
      <h1>{t('Welcome to React')}</h1>
    )
  }
}
const MyComponent = withTranslation()(LegacyComponentClass)

// i18n translations might still be loaded by the http backend
// use react's Suspense
export default function App() {
  return (
    <Suspense fallback="loading">
      <MyComponent />
    </Suspense>
  );
}
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
import React, { Component, Suspense } from 'react';
import { withTranslation } from 'react-i18next';

class LegacyComponentClass extends Component {
  render() {
    const { t } = this.props;

    return (
      <h1>{t($ => $['Welcome to React'])}</h1>
    )
  }
}
const MyComponent = withTranslation()(LegacyComponentClass)

// i18n translations might still be loaded by the http backend
// use react's Suspense
export default function App() {
  return (
    <Suspense fallback="loading">
      <MyComponent />
    </Suspense>
  );
}
```

{% endtab %}
{% endtabs %}

The withTranslation hook function takes one options argument. You can either pass in a namespace or a array of namespaces to load.

```javascript
withTranslation('common')(LegacyComponentClass);

withTranslation(['page1', 'common'])(LegacyComponentClass);
```

#### Using the Trans component

The Trans component is the best way to translate a JSX tree in one translation. This enables you to eg. easily translate text containing a link component or formatting like `<strong>`.

```jsx
import React from 'react';
import { Trans } from 'react-i18next';

export default function MyComponent () {
  return <Trans>Welcome to <strong>React</strong></Trans>
}

// the translation in this case should be
"Welcome to <1>React</1>": "Welcome to <1>React and react-i18next</1>"
```

Don't worry if you do not yet understand how the Trans component works in detail. Learn more about it [here](/latest/trans-component).

## See the sample

Prefer having code to checkout? Directly dive into our example:

* [using hooks with react-i18next](https://github.com/i18next/react-i18next/tree/master/example/react)

### Do you like to read a more complete step by step tutorial?

{% hint style="success" %}
[Here](https://www.locize.com/blog/react-i18next/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=latest_using_with_hooks) you'll find a simple tutorial on how to best use react-i18next.\
Some basics of i18next and some cool possibilities on how to optimize your localization workflow.[\
![](/files/-MYGrwr09aHCLauHUHx9)](https://www.locize.com/blog/react-i18next/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=latest_using_with_hooks)
{% endhint %}


# i18next instance

The instance is an initialized i18next instance. In the following code snippet, we add a backend to load translations from server and a language detector for detecting user language.

> You can learn more about [i18next](https://i18next.com) and [plugins](https://www.i18next.com/overview/plugins-and-utils) on the i18next website.

```javascript
import i18n from 'i18next';
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
import { initReactI18next } from 'react-i18next';


i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next) // bind react-i18next to the instance
  .init({
    fallbackLng: 'en',
    debug: true,

    interpolation: {
      escapeValue: false, // not needed for react!!
    },

    // react i18next special options (optional)
    // override if needed - omit if ok with defaults
    /*
    react: {
      bindI18n: 'languageChanged',
      bindI18nStore: '',
      transEmptyNodeValue: '',
      transSupportBasicHtmlNodes: true,
      transKeepBasicHtmlNodesFor: ['br', 'strong', 'i'],
      useSuspense: true,
    }
    */
  });


export default i18n;
```

All additional options for react in init options:

| options                    | default                     | description                                                                                                                                                                                                           |
| -------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| bindI18n                   | 'languageChanged'           | <p>which events trigger a rerender, can be set to false or string of events<br>separated by ""</p>                                                                                                                    |
| bindI18nStore              | ''                          | define which events on [resourceStore](https://www.i18next.com/overview/api#store-events) should trigger a rerender                                                                                                   |
| transEmptyNodeValue        | ''                          | how to treat failed lookups in Trans component                                                                                                                                                                        |
| transSupportBasicHtmlNodes | true                        | <p>convert eg. <code>\<br/></code> found in translations to a react component of type br<br><a href="/pages/-LY2DIN9rfhmF1Wk64Ak#using-for-simple-html-elements-in-translations-v-10-4-0">See Trans component</a></p> |
| transKeepBasicHtmlNodesFor | \['br', 'strong', 'i', 'p'] | <p>Which nodes not to convert in defaultValue generation in the Trans component.<br><a href="/pages/-LY2DIN9rfhmF1Wk64Ak#using-for-simple-html-elements-in-translations-v-10-4-0">See Trans component</a></p>         |
| useSuspense                | true                        | If using Suspense or not                                                                                                                                                                                              |
| keyPrefix                  | undefined                   | the optional `keyPrefix` will be automatically applied to the returned `t` function in [useTranslation](/latest/usetranslation-hook#optional-keyprefix-option) for example.                                           |

For more initialization options have look at the [docs](https://www.i18next.com/overview/configuration-options).


# useTranslation (hook)

## What it does

It gets the `t` function and `i18n` instance inside your functional component.

{% tabs %}
{% tab title="JavaScript" %}

```jsx
import React from 'react';
import { useTranslation } from 'react-i18next';

export function MyComponent() {
  const { t, i18n } = useTranslation(); // not passing any namespace will use the defaultNS (by default set to 'translation')
  // or const [t, i18n] = useTranslation();

  return <p>{t('my translated text')}</p>
}
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
import React from 'react';
import { useTranslation } from 'react-i18next';

export function MyComponent() {
  const { t, i18n } = useTranslation(); // not passing any namespace will use the defaultNS (by default set to 'translation')
  // or const [t, i18n] = useTranslation();

  return <p>{t($ => $['my translated text'])}</p>
}
```

{% endtab %}
{% endtabs %}

While most of the time you only need the `t` function to translate your content, you can also get the i18n instance (in order to change the language).

```javascript
i18n.changeLanguage('en-US');
```

{% hint style="info" %}
The `useTranslation` hook will trigger a [Suspense](https://reactjs.org/docs/concurrent-mode-suspense.html) if not ready (eg. pending load of translation files). You can set `useSuspense` to false if prefer not using Suspense.
{% endhint %}

## When to use?

Use the `useTranslation` hook inside your **functional components** to access the translation function or i18n instance.

{% hint style="success" %}
In [this tutorial](https://www.locize.com/blog/react-i18next/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=latest_usetranslation_hook\&from=i18next_react-usetranslation-hook__hint) you'll find some ways on how to use this useTranslation hook.

You'll also see how to use it when you need to work with [multiple namespaces](https://www.locize.com/blog/react-i18next/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=latest_usetranslation_hook\&from=i18next_react-usetranslation-hook__hint#multiple-namespaces).[\ <img src="/files/-MYGrwr09aHCLauHUHx9" alt="" data-size="original">](https://www.locize.com/blog/react-i18next/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=latest_usetranslation_hook\&from=i18next_react-usetranslation-hook__hint)
{% endhint %}

## useTranslation params

### Loading namespaces

{% tabs %}
{% tab title="JavaScript" %}

<pre class="language-jsx"><code class="lang-jsx"><strong>// load a specific namespace
</strong><strong>// the t function will be set to that namespace as default
</strong>const { t, i18n } = useTranslation('ns1');
t('key'); // will be looked up from namespace ns1

// load multiple namespaces
// the t function will be set to first namespace as default
const { t, i18n } = useTranslation(['ns1', 'ns2', 'ns3']);
t('key'); // will be looked up from namespace ns1
t('key', { ns: 'ns2' }); // will be looked up from namespace ns2
</code></pre>

{% endtab %}

{% tab title="TypeScript" %}

```tsx
// load a specific namespace
// the t function will be set to that namespace as default
const { t, i18n } = useTranslation('ns1');
t('key'); // will be looked up from namespace ns1

// load multiple namespaces
// the t function will be set to first namespace as default
const { t, i18n } = useTranslation(['ns1', 'ns2', 'ns3']);
t($ => $.key); // will be looked up from namespace ns1
t($ => $.key, { ns: 'ns2' }); // will be looked up from namespace ns2

// since react-i18next v17.0.7 / i18next v26.0.10 a selector path whose first
// segment matches a *secondary* namespace is routed to that namespace too:
t($ => $.ns2.key); // will be looked up from namespace ns2
t($ => $.ns3.deep.key); // will be looked up from namespace ns3
// the primary namespace ('ns1' here) is never rewritten — `$.ns1.key` would
// mean a literal sub-key inside ns1 rather than a switch.
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
Only the `t` function is bound to the namespace, behind the scenes it uses the [getFixedT](https://www.i18next.com/overview/api#getfixedt) function of i18next.\
The `i18n` instance is the normal i18next instance. Not bound to anything special.
{% endhint %}

{% hint style="info" %}
**Selector ns prefix vs. resolution scope.** Plain `t('key')` calls remain isolated to the **primary** namespace under default `nsMode` — they don't fall through to the secondary namespaces. Only the **selector**'s first segment is matched against the hook's full namespace list, via the new `scopeNs` argument that `useTranslation` now passes to `getFixedT`. If you want `t('key')` to fall through to all namespaces in order, use `nsMode: 'fallback'` (unchanged from before).
{% endhint %}

### Overriding the i18next instance

```javascript
// passing in an i18n instance
// use only if you do not like the default instance
// set by i18next.use(initReactI18next) or the I18nextProvider
import i18n from './i18n';
const { t, i18n } = useTranslation('ns1', { i18n });
```

### Optional keyPrefix option

> available in react-i18next version >= 11.12.0
>
> depends on i18next version >= 20.6.0

{% tabs %}
{% tab title="JavaScript" %}

```jsx
// having JSON in namespace "translation" like this:
/*{
    "very": {
      "deeply": {
        "nested": {
          "key": "here"
        }
      }
    }
}*/
// you can define a keyPrefix to be used for the resulting t function
const { t } = useTranslation('translation', { keyPrefix: 'very.deeply.nested' });
const text = t('key'); // "here"
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
// having JSON in namespace "translation" like this:
/*{
    "very": {
      "deeply": {
        "nested": {
          "key": "here"
        }
      }
    }
}*/
// you can define a keyPrefix to be used for the resulting t function
const { t } = useTranslation('translation', { keyPrefix: 'very.deeply.nested' });
const text = t($ => $.key); // "here"
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="JavaScript" %}
{% hint style="warning" %}
Do **not** use the `keyPrefix` option if you want to use keys with prefixed namespace notation:

i.e.

```javascript
const { t } = useTranslation('translation', { keyPrefix: 'very.deeply.nested' });
const text = t('ns:key'); // this will not work
```

{% endhint %}
{% endtab %}

{% tab title="TypeScript" %}
{% hint style="warning" %}
Do **not** use the `keyPrefix` option if you want to use keys with prefixed namespace notation:

i.e.

```javascript
const { t } = useTranslation('translation', { keyPrefix: 'very.deeply.nested' });
const text = t($ => $.key, { ns: 'ns' }); // this will not work
```

{% endhint %}
{% endtab %}
{% endtabs %}

### Optional lng option

> available in react-i18next version >= 12.3.1

{% tabs %}
{% tab title="JavaScript" %}

```jsx
// you can pass a language to be used for the resulting t function
const { t } = useTranslation('translation', { lng: 'de' });
const text = t('key'); // "hier"
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
// you can pass a language to be used for the resulting t function
const { t } = useTranslation('translation', { lng: 'de' });
const text = t($ => $.key); // "hier"
```

{% endtab %}
{% endtabs %}

### Not using Suspense

```javascript
// additional ready will state if translations are loaded or not
const { t, i18n, ready } = useTranslation('ns1', { useSuspense: false });
```

{% hint style="info" %}
Not using Suspense you will need to handle the not ready state yourself by eg. render a loading component as long `!ready` . Not doing so will result in rendering your translations before they loaded which will cause save missing be called although translations exists (just yet not loaded).
{% endhint %}

### Troubleshooting

**Blank screen or "suspended while rendering, but no fallback UI was specified"?** `useSuspense` is `true` by default: while translations load asynchronously (http backend, locize backend, ...), the component suspends. Either wrap it in a `<Suspense fallback={...}>` boundary, or set `useSuspense: false` and handle the `ready` flag as shown above. Since v17.0.10 a development-only console warning points this out when it happens.

**"Rendered more hooks than during the previous render" pointing at `useTranslation`?** This was a bug in react-i18next < 16.3 (an early return before all hooks ran when the i18next instance wasn't ready yet, typically under init/render races or React StrictMode). It is fixed in >= 16.3; upgrade instead of working around it.


# withTranslation (HOC)

## What it does

The `withTranslation` is a classic HOC (higher order component) and gets the `t` function and `i18n` instance inside your component via props.

{% tabs %}
{% tab title="JavaScript" %}

```jsx
import React from 'react';
import { withTranslation } from 'react-i18next';

function MyComponent({ t, i18n }) {
  return <p>{t('my translated text')}</p>
}

export default withTranslation()(MyComponent);
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
import React from 'react';
import { withTranslation } from 'react-i18next';

function MyComponent({ t, i18n }) {
  return <p>{t($ => $['my translated text'])}</p>
}

export default withTranslation()(MyComponent);
```

{% endtab %}
{% endtabs %}

While you most time only need the t function to translate your content you also get the i18n instance to eg. change the language.

```javascript
i18n.changeLanguage('en-US');
```

{% hint style="info" %}
The `withTranslation` HOC will trigger a [Suspense](https://reactjs.org/docs/code-splitting.html#suspense) if not ready (eg. pending load of translation files). You can set `useSuspense` to false if prefer not using Suspense.
{% endhint %}

## When to use?

Use the `withTranslation` HOC to wrap **any component (class or function)** to access the translation function or i18n instance.

## withTranslation params

### Loading namespaces

{% tabs %}
{% tab title="JavaScript" %}

```jsx
// load a specific namespace
// the t function will be set to that namespace as default
withTranslation('ns1')(MyComponent);

// inside your component MyComponent
this.props.t('key'); // will be looked up from namespace ns1

// load multiple namespaces
// the t function will be set to first namespace as default
withTranslation(['ns1', 'ns2', 'ns3'])(MyComponent);

// inside your component MyComponent
this.props.t('key'); // will be looked up from namespace ns1
this.props.t('key', { ns: 'ns2' }); // will be looked up from namespace ns2
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
// load a specific namespace
// the t function will be set to that namespace as default
withTranslation('ns1')(MyComponent);

// inside your component MyComponent
this.props.t($ => $.key); // will be looked up from namespace ns1

// load multiple namespaces
// the t function will be set to first namespace as default
withTranslation(['ns1', 'ns2', 'ns3'])(MyComponent);

// inside your component MyComponent
this.props.t($ => $.key); // will be looked up from namespace ns1
this.props.t($ => $.key, { ns: 'ns2' }); // will be looked up from namespace ns2
```

{% endtab %}
{% endtabs %}

### Overriding the i18next instance

```javascript
// passing in an i18n instance
// use only if you do not like the default instance
// set by i18next.use(initReactI18next) or the I18nextProvider
import i18n from './i18n';

const ExtendedComponent = withTranslation('ns1')(MyComponent);

<ExtendedComponent i18n={i18n} />
```

### Not using Suspense

```javascript
// use tReady prop in MyComponent to check if translations
// are already loaded or not
const ExtendedComponent = withTranslation()(MyComponent);

<ExtendedComponent useSuspense={false} />
```

{% hint style="info" %}
Not using Suspense you will need to handle the not ready state yourself by eg. render a loading component as long `!props.tReady` . Not doing so will result in rendering your translations before they loaded which will cause save missing be called although translations exist (just yet not loaded).
{% endhint %}

## How to

### use ref (>= v10.6.0)

You can use forwardRefs like:

```jsx
const Wrapped = withTranslation('translation', { withRef: true })(MyComponent);

// then pass a ref in your render method like
const myRef = React.createRef();
<Wrapped ref={myRef} />;

// use myRef.current to access it
```

### hoist non-react statics

The HOC does not hoist statics itself so you might append those statics manually or by using a module.

Use [hoist-non-react-statics](https://github.com/mridgway/hoist-non-react-statics) yourself:

```jsx
import React, { Component } from 'react';
import { withTranslation } from 'react-i18next';
import hoistStatics from 'hoist-non-react-statics';

class MyComponent extends Component {
  static ...
}

export default hoistStatics(withTranslation()(MyComponent), MyComponent);
```

Or simply hoist the one/two statics yourself:

```jsx
import React, { Component } from 'react';
import { withTranslation } from 'react-i18next';
import hoistStatics from 'hoist-non-react-statics';

class MyComponent extends Component {
  static ...
}

const Extended = withTranslation()(MyComponent);
Extended.static = MyComponent.static;

export default Extended;
```

### use TypeScript with class components

To get proper type annotations while using TypeScript, import the interface `WithTranslation` and extend it with your own props interface.

{% tabs %}
{% tab title="JavaScript" %}

```jsx
import React, { Component } from 'react';
import { withTranslation, WithTranslation } from 'react-i18next';

class MyComponent extends Component {
  render() {
    return <div>{this.props.t('My translated text')}</div>
  }
}

export default withTranslation()(MyComponent);
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
import React, { Component } from 'react';
import { withTranslation, WithTranslation } from 'react-i18next';

class MyComponent extends Component<IProps, IState> {
  render() {
    return <div>{this.props.t($ => $['My translated text'])}</div>
  }
}

interface IProps extends WithTranslation {
  prop: any;
}

interface IState {
  state: any;
}

export default withTranslation()(MyComponent);
```

{% endtab %}
{% endtabs %}


# Translation (render prop)

## What it does <a href="#what-it-does" id="what-it-does"></a>

The `Translation` is a render prop and gets the `t` function and `i18n` instance to your component.

{% tabs %}
{% tab title="JavaScript" %}

```jsx
import React from 'react';
import { Translation } from 'react-i18next';

export function MyComponent() {
  return (
    <Translation>
      {
        (t, { i18n }) => <p>{t('my translated text')}</p>
      }
    </Translation>
  )
}
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
import React from 'react';
import { Translation } from 'react-i18next';

export function MyComponent() {
  return (
    <Translation>
      {
        (t, { i18n }) => <p>{t($ => $['my translated text'])}</p>
      }
    </Translation>
  )
}
```

{% endtab %}
{% endtabs %}

While you most time only need the t function to translate your content you also get the i18n instance to eg. change the language.

```javascript
i18n.changeLanguage('en-US');
```

{% hint style="info" %}
The `Translation` render prop will trigger a [Suspense](https://reactjs.org/docs/code-splitting.html#suspense) if not ready (eg. pending load of translation files). You can set `useSuspense` to false if prefer not using Suspense.
{% endhint %}

## When to use?

Use the `Translation` render prop inside **any component (class or function)** to access the translation function or i18n instance.

## Translation params

### Loading namespaces

{% tabs %}
{% tab title="JavaScript" %}

```jsx
// load a specific namespace
// the t function will be set to that namespace as default
<Translation ns="ns1">
{
  (t) => <p>{t('my translated text')}</p> // will be looked up from namespace ns1
}
</Translation>

// load multiple namespaces
// the t function will be set to first namespace as default
<Translation ns={['ns1', 'ns2', 'ns3']}>
{
  (t) => <p>{t('my translated text')}</p> // will be looked up from namespace ns1
}
</Translation>
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
// load a specific namespace
// the t function will be set to that namespace as default
<Translation ns="ns1">
{
  (t) => <p>{t($ => $['my translated text'])}</p> // will be looked up from namespace ns1
}
</Translation>

// load multiple namespaces
// the t function will be set to first namespace as default
<Translation ns={['ns1', 'ns2', 'ns3']}>
{
  (t) => <p>{t($ => $['my translated text'])}</p> // will be looked up from namespace ns1
}
</Translation>
```

{% endtab %}
{% endtabs %}

### Overriding the i18next instance

{% tabs %}
{% tab title="JavaScript" %}

```jsx
// passing in an i18n instance
// use only if you do not like the default instance
// set by i18next.use(initReactI18next) or the I18nextProvider
import i18n from './i18n';

<Translation i18n={i18n}>
{
  (t, { i18n }) => <p>{t('my translated text')}</p> // will be looked up from namespace ns1
}
</Translation>
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
// passing in an i18n instance
// use only if you do not like the default instance
// set by i18next.use(initReactI18next) or the I18nextProvider
import i18n from './i18n';

<Translation i18n={i18n}>
{
  (t, { i18n }) => <p>{t($ => $['my translated text'])}</p> // will be looked up from namespace ns1
}
</Translation>
```

{% endtab %}
{% endtabs %}


# Trans Component

{% hint style="success" %}
🎉 Announcing [`i18next-cli`](https://github.com/i18next/i18next-cli):\
The New Official Toolkit for i18next.\
⇒ [Learn More](https://www.locize.com/blog/i18next-cli?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=latest_trans_component\&from=i18next_react-trans-component__learnmore)
{% endhint %}

## Important note

While `<Trans>` gives you a lot of power by letting you interpolate or translate complex React elements, the truth is: in most cases you don't even need it.

**As long you have no React/HTML nodes integrated into a cohesive sentence** (text formatting like `strong`, `em`, link components, maybe others), **you won't need it** - most of the times you will be using the good old `t` function.

You may be looking directly for the [Trans props](https://react.i18next.com/latest/trans-component#trans-props).

{% hint style="warning" %}
It does ONLY interpolation. It does not rerender on language change or load any translations needed. Check [`useTranslation` hook](/latest/usetranslation-hook) or [`withTranslation` HOC](/latest/withtranslation-hoc) for those cases.
{% endhint %}

```javascript
import React from 'react';
import { Trans, useTranslation } from 'react-i18next'

function MyComponent() {
  const { t } = useTranslation('myNamespace');

  return <Trans t={t}>Hello World</Trans>;
}
```

{% hint style="info" %}
Have a look at the [i18next documentation](https://www.i18next.com) for details on the the `t` function:

* [essentials](https://www.i18next.com/translation-function/essentials.html)
* [interpolation](https://www.i18next.com/translation-function/interpolation.html)
* [formatting](https://www.i18next.com/translation-function/formatting.html)
* [plurals](https://www.i18next.com/translation-function/plurals.html)
  {% endhint %}

## Samples

### Using with React components

So you learned there is no need to use the Trans component everywhere (the plain `t` function will just do fine in most cases).

This component enables you to nest any React content to be translated as one cohesive string. It supports both plural and interpolation. The `<Trans>` component will automatically use the most relevant `t()` function (from the [context instance](https://react.i18next.com/latest/i18nextprovider) or the global instance), unless overridden via the `i18n` or `t` props.

{% hint style="success" %}
**Tip:** most projects find the **named-components form** the easiest to read and maintain: `components={{ bold: <strong />, myLink: <Link to="/msgs" /> }}` with `<bold>...</bold>` / `<myLink>...</myLink>` tags in the translation string. See [Alternative usage which lists the components](#alternative-usage-which-lists-the-components-v11.6.0). The indexed form (`<0>`, `<1>`) shown below is what it desugars to and what you will meet in older codebases and extraction tools. Also good to know: a literal `<` character inside a translation string (e.g. `count < 10`) is handled correctly since react-i18next 16.2.2; older versions tried to parse it as a tag.
{% endhint %}

*Let's say you want to create following HTML output:*

> Hello **Arthur**, you have 42 unread messages. [Go to messages](/latest/trans-component).

**Before:** Your untranslated React code would have looked something like:

```javascript
function MyComponent({ person, messages }) {
  const { name } = person;
  const count = messages.length;

  return (
    <>
      Hello <strong title="This is your name">{name}</strong>, you have {count} unread message(s). <Link to="/msgs">Go to messages</Link>.
    </>
  );
}
```

**After:** With the Trans component just change it to:

{% tabs %}
{% tab title="JavaScript" %}

```jsx
import { Trans } from 'react-i18next';

function MyComponent({ person, messages }) {
  const { name } = person;
  const count = messages.length;

  return (
    <Trans i18nKey="userMessagesUnread" count={count}>
      Hello <strong title={t('nameTitle')}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
    </Trans>
  );
}
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
import { Trans } from 'react-i18next';

function MyComponent({ person, messages }) {
  const { name } = person;
  const count = messages.length;

  return (
    <Trans i18nKey="userMessagesUnread" count={count}>
      Hello <strong title={t($ => $.nameTitle)}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
    </Trans>
  );
}
```

{% endtab %}
{% endtabs %}

*Your en.json (translation strings) will look like:*

```javascript
"nameTitle": "This is your name",
"userMessagesUnread_one": "Hello <1>{{name}}</1>, you have {{count}} unread message. <5>Go to message</5>.",
"userMessagesUnread_other": "Hello <1>{{name}}</1>, you have {{count}} unread messages.  <5>Go to messages</5>.",
```

{% hint style="info" %}
[**saveMissing**](https://www.i18next.com/overview/configuration-options#missing-keys) will send a valid `defaultValue` based on the component children.\
Also, The `i18nKey` is optional, in case you already use text as translation keys.
{% endhint %}

### Alternative usage which lists the components (v11.6.0)

```javascript
<Trans
  i18nKey="myKey" // optional -> fallbacks to defaults if not provided
  defaults="hello <italic>beautiful</italic> <bold>{{what}}</bold>" // optional defaultValue
  values={{ what: 'world'}}
  components={{ italic: <i />, bold: <strong /> }}
/>
```

This format is useful if you want to interpolate the same node multiple times. Another advantage is the simpler named tags, which avoids the trouble with index guessing - however, this can also be achieved with `transSupportBasicHtmlNodes`, see the next section.

{% hint style="warning" %}
Existing self-closing HTML tag names are reserved keys and won't work. Examples: `link: <Link />`, `img: <img src="" />`, `media: <img src="" />`
{% endhint %}

{% hint style="info" %}
Make sure you also adapt your translation resources to include the *named tags* (`<italic>`) instead of the *indexed tags* (`<0>`)!
{% endhint %}

### Overriding React component props (v11.5.0)

In some cases you may want to override the props of a given component based on the active language.

This can be achieved by providing prop values inside of your translations. Such values will override whatever has been passed to the component present in the `components` prop of the `Trans` component.

In the example below we want our custom link component to have a different `href` value based on the active language. This is how our custom link component is being used:

```javascript
<Trans
  i18nKey="myKey"
  components={{ 
    CustomLink: <MyCustomLinkComponent href="value-to-be-overridden"/> 
  }}
/>
```

with the following being our translation message:

```json
"myKey": "This is a <CustomLink href=\"https://example.com/\">link to example.com</CustomLink>."
```

This setup will render the following JSX:

```html
This is a <MyCustomLinkComponent href="https://example.com/">link to example.com</MyCustomLinkComponent>.
```

This approach also works with listed components:

```javascript
<Trans
  i18nKey="myKey"
  components={[ <MyCustomLinkComponent href="value-to-be-overridden"/> ]}
/>
```

With this then making up our translation message:

```json
"myKey": "This is a <0 href=\"https://example.com/\">link to example.com</0>."
```

### Usage with simple HTML elements like \<br /> and others (v10.4.0)

There are two options that allow you to have basic HTML tags inside your translations, instead of numeric indexes. However, this only works for elements without additional attributes (like `className`), having none or a single text children.

Examples of elements that will be readable in translation strings:

* `<br/>`
* `<strong>bold</strong>`
* `<p>some paragraph</p>`

Examples that will be converted to indexed nodes:

* `<i className="icon-gear" />`: no attributes allowed
* `<strong title="something">{{name}}</strong>`: only text nodes allowed
* `<b>bold <i>italic</i></b>`: no nested elements, even simple ones

```jsx
<Trans i18nKey="welcomeUser">
  Hello <strong>{{name}}</strong>. <Link to="/inbox">See my profile</Link>
</Trans>
// JSON -> "welcomeUser": "Hello <strong>{{name}}</strong>. <1>See my profile</1>"

<Trans i18nKey="multiline">
  Some newlines <br/> would be <br/> fine
</Trans>
// JSON -> "multiline": "Some newlines <br/> would be <br/> fine"
```

Here is what can be configured in `i18next.options.react` that affect this behaviour:

| Option                          | Default                      | Description                                                                                                                                                                                                                                                             |
| ------------------------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transSupportBasicHtmlNodes`    | `true`                       | Enables keeping the name of simple nodes (e.g. `<br/>`) in translations instead of indexed keys                                                                                                                                                                         |
| `transKeepBasicHtmlNodesFor`    | `['br', 'strong', 'i', 'p']` | Which nodes are allowed to be kept in translations during `defaultValue` generation of `<Trans>`.                                                                                                                                                                       |
| `transWrapTextNodes` (v11.10.0) | `''`                         | Wrap text nodes in a user-specified element. e.g. set it to `span`. By default, text nodes are not wrapped. Can be used to work around a well-known Google Translate issue with React apps. See [facebook/react#11538](https://github.com/facebook/react/issues/11538). |

### Interpolation

You can pass in variables to get interpolated into the translation string by using objects containing those key:values.

```jsx
const person = { name: 'Henry', age: 21 };
const { name, age } = person;

<Trans>
  Hello {{ name }}. // <- = {{ "name": name }}
</Trans>
// Translation string: "Hello {{name}}"


<Trans>
  Hello {{ firstname: person.name }}.
</Trans>
// Translation string: "Hello {{firstname}}"
```

#### TypeScript Usage

When using TypeScript, you may encounter a type error when interpolating variables within React elements:

```tsx
<Trans>
  Hello <i>{{name}}</i>
</Trans>
// Error: Object literal may only specify known properties...
```

This occurs because React's type definitions don't expect object literals as children. Since `react-i18next` transforms these at runtime, you can safely work around this with a type assertion:

```tsx
// Create a reusable type helper
type TransInterpolation = Record<string, string | number>;

<Trans>
  Hello <i>{{name} as TransInterpolation}</i>
</Trans>
```

For simpler cases, you can also cast directly to `any`:

```tsx
<Trans>
  Hello <i>{{name} as any}</i>
</Trans>
```

**Note:** Avoid using the `allowObjectInHTMLChildren` compiler option, as this weakens type safety globally across your entire React application. But if you're ok with that, this is also a valid option.

### Plural

You will need to pass the `count` prop:

```jsx
const messages = ['message one', 'message two'];

<Trans i18nKey="newMessages" count={messages.length}>
  You have {{ count: messages.length }} messages.
</Trans>

// Translation strings:
// "newMessages": "You have one message."
// "newMessages_plural": "You have {{count}} messages."
```

As of v16.4.0, the `count` prop is optional when `{{ count }}` is present in the children, react-i18next will infer it automatically by walking the children tree.

{% hint style="info" %}
**Notes:**

* Inference requires `count` to be a JavaScript **number**. A string value will not be inferred.
* An explicit `count` prop always takes precedence over any inferred value, including `count={0}`.
* Without children (key-only form), the `count` prop remains required.
  {% endhint %}

### Using with lists (v10.5.0)

You can still use `Array.map()` to turn dynamic content into nodes, using an extra option on a wrapping element:

```jsx
<Trans i18nKey="list_map">
  My dogs are named:
  <ul i18nIsDynamicList>
    {['rupert', 'max'].map(dog => (<li>{dog}</li>))}
  </ul>
</Trans>
// JSON -> "list_map": "My dogs are named: <1></1>"
```

Setting `i18nIsDynamicList` on the parent element will assert the `nodeToString` function creating the string for `saveMissing` will not contain children.

### Alternative usage (components array)

Some use cases, such as the ICU format, might be simpler by just passing content as props:

```javascript
<Trans
  i18nKey="myKey" // optional -> fallbacks to defaults if not provided
  defaults="hello <0>{{what}}</0>" // optional defaultValue
  values={{ what: 'world'}}
  components={[<strong>univers</strong>]}
/>
```

{% hint style="info" %}
`<0>` -> 0 is the index of the component in the components array
{% endhint %}

E.g. this format is needed when using [ICU as translation format](https://github.com/i18next/i18next-icu) as it is not possible to have the needed syntax as children (invalid jsx).

## How to get the correct translation string?

Guessing replacement tags *(<0>\</0>)* of your component is rather difficult. There are four options to get those translations directly generated by i18next:

1. use React Developer Tools to inspect the `<Trans>` component instance and look at the `props.children` array for array index of the tag in question.
2. use `debug = true` in `i18next.init()` options and watch your console for the missing key output
3. use the [saveMissing feature](https://www.i18next.com/configuration-options#missing-keys) of i18next to get those translations pushed to your backend or handled by a custom function.
4. understand how those numbers get generated from child index:

**Sample JSX:**

{% tabs %}
{% tab title="JavaScript" %}

```jsx
<Trans i18nKey="userMessagesUnread" count={count}>
  Hello <strong title={t('nameTitle')}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
</Trans>
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
<Trans i18nKey="userMessagesUnread" count={count}>
  Hello <strong title={t($ => $.nameTitle)}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
</Trans>
```

{% endtab %}
{% endtabs %}

**Resulting translation string:**

```
"Hello <1>{{name}}</1>, you have {{count}} unread message. <5>Go to message</5>."
```

**The complete the node tree**:

```javascript
Trans.children = [
  'Hello ',                         // 0: only a string
  { children: [{ name: 'Jan' }] },  // 1: <strong> with child object for interpolation
  ', you have ',                    // 2: only a string
  { count: 10 },                    // 3: plain object for interpolation
  ' unread messages. ',             // 4: only a string
  { children: ['Go to messages'] }, // 5: <Link> with a string child
  '.'                               // 6: yep, you guessed: another string
]
```

**Rules:**

* child is a string: nothing to wrap; just take the string
* child is an object: nothing to do; it's used for interpolation
* child is an element: wrap it's children in `<x></x>` where `x` is the index of that element's position in the `children` list; handle its children with the same rules (starting `element.children` index at 0 again)

{% hint style="info" %}
These indexed tags are hard for translators too: a `<0></0>` moved to the wrong place breaks the sentence, and a plain spreadsheet gives no clue what element `0` even is. Showing the string where it actually renders avoids most of it. [Locize](https://www.locize.com/i18next?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=latest_trans_component\&from=i18next_react-trans-component__hint), the TMS built by the i18next team, has an in-context editor for translating directly on your running app, plus screenshot context per key, and keeps the tag structure intact.
{% endhint %}

## Trans props

All properties are optional, although you'll need to use `i18nKey` if you're not using natural language keys (text-based).

| ***name***          | ***type (default)***       | ***description***                                                                                                                                                                                                                                                                                                                                                                                                                |
| ------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `i18nKey`           | `string (undefined)`       | <p>If you prefer to use text as keys you can omit this, and the translation will be used as key. Can contain the namespace by prepending it in the form <code>'ns:key'</code> (depending on <code>i18next.options.nsSeparator</code>)</p><p>But this is not recommended when used in combination with natural language keys, better use the dedicated ns parameter: <code>\<Trans i18nKey="myKey" ns="myNS">\</Trans></code></p> |
| `ns`                | `string (undefined)`       | Namespace to use. May also be embedded in `i18nKey` but not recommended when used in combination with natural language keys, see above.                                                                                                                                                                                                                                                                                          |
| `t`                 | `function (undefined)`     | `t` function to use instead of the global `i18next.t()` or the `t()` function provided by the nearest [provider](https://react.i18next.com/latest/i18nextprovider).                                                                                                                                                                                                                                                              |
| `count`             | `integer (undefined)`      | Numeric value for pluralizable strings. As of v16.4.0, optional when `{{ count }}` appears in children, the value will be inferred automatically. Must be a JavaScript `number` for inference to work. An explicit prop always takes precedence. Still required when using `<Trans>` without children.                                                                                                                           |
| `context`           | `string (undefined)`       | Value used for the [context feature](https://www.i18next.com/translation-function/context).                                                                                                                                                                                                                                                                                                                                      |
| `tOptions`          | `object (undefined)`       | Extra options to pass to `t()` (e.g. `context`, `postProcessor`, ...)                                                                                                                                                                                                                                                                                                                                                            |
| `parent`            | `node (undefined)`         | A component to wrap the content into (can be globally set on `i18next.init`). **Required for React < v16**                                                                                                                                                                                                                                                                                                                       |
| `i18n`              | `object (undefined)`       | i18next instance to use if not provided by context                                                                                                                                                                                                                                                                                                                                                                               |
| `defaults`          | `string (undefined)`       | Use this instead of using the children as default translation value (useful for ICU)                                                                                                                                                                                                                                                                                                                                             |
| `values`            | `object (undefined)`       | Interpolation values if not provided in children                                                                                                                                                                                                                                                                                                                                                                                 |
| `components`        | `array[nodes] (undefined)` | Components to interpolate based on index of tag                                                                                                                                                                                                                                                                                                                                                                                  |
| `shouldUnescape`    | `boolean (false)`          | HTML encoded tags like: `&lt; &amp; &gt;` should be unescaped, to become: `< & >`                                                                                                                                                                                                                                                                                                                                                |
| `transDefaultProps` | `object (undefined)`       | Default props for the `Trans` component. Can be used to set default values for `tOptions`, `shouldUnescape`, `values`, and `components`.                                                                                                                                                                                                                                                                                         |

### i18next options

```javascript
i18next.init({
  // ...
  react: {
    // ...
    hashTransKey: function(defaultValue) {
      // return a key based on defaultValue or if you prefer to just remind you should set a key return false and throw an error
    },
    defaultTransParent: 'div', // a valid react element - required before react 16
    transEmptyNodeValue: '', // what to return for empty Trans
    transSupportBasicHtmlNodes: true, // allow <br/> and simple html elements in translations
    transKeepBasicHtmlNodesFor: ['br', 'strong', 'i'], // don't convert to <1></1> if simple react elements
    transWrapTextNodes: '', // Wrap text nodes in a user-specified element.
                            // i.e. set it to 'span'. By default, text nodes are not wrapped.
                            // Can be used to work around a well-known Google Translate issue with React apps. See: https://github.com/facebook/react/issues/11538
                            // (v11.10.0)
    transDefaultProps: undefined, // default props for Trans component
    // {
    //   tOptions: { interpolation: { escapeValue: true } },
    //   shouldUnescape: true,
    //   values: {},
  }
});
```

{% hint style="warning" %}
Please be aware if you are using **React 15 or below**, you are required to set the `defaultTransParent` option, or pass a `parent` via props.
{% endhint %}

{% hint style="danger" %}
**Are you having trouble when your website is ran through Google Translate?**\
Google Translate seems to manipulate the DOM and makes React quite unhappy!\
**There's a work around:** you can wrap text nodes with`<span>` using `transWrapTextNodes: 'span'`.

*If you want to know more about the Google Translate issue with React, have a look at* [*this*](https://github.com/facebook/react/issues/11538#issuecomment-390386520)*.*
{% endhint %}


# IcuTrans Component

## Important note

This component is an alternative component to [`Trans`](/latest/trans-component) which is designed for use as the internal implementation of [The `icu.macro` Babel macro](/misc/using-with-icu-format). Using it directly is possible, but not recommended.

While `<IcuTrans>` gives you a lot of power by letting you interpolate or translate complex React elements, the truth is: in most cases don't need this power.

**As long you have no React/HTML nodes integrated into a cohesive sentence** (text formatting like `strong`, `em`, link components, maybe others), **you won't need it** - most of the times you will be using the good old `t` function.

[IcuTrans props reference](https://react.i18next.com/latest/icu-trans-component#icutrans-props).

{% hint style="warning" %}
IcuTrans does ONLY interpolation. It does not rerender on language change or load any translations needed. Use [`useTranslation` hook](/latest/usetranslation-hook) or [`withTranslation` HOC](/latest/withtranslation-hoc) with `IcuTrans` to force a re-render on language changes.
{% endhint %}

```javascript
import React from 'react';
import { IcuTrans, useTranslation } from 'react-i18next'

function MyComponent() {
  // this will force a re-render when language changes or translation files are loaded
  const { t } = useTranslation('myNamespace');

  return <IcuTrans defaultTranslation="Hello World" content={[]} t={t}>Hello World</IcuTrans>;
}
```

{% hint style="info" %}
Have a look at the [i18next documentation](https://www.i18next.com) for details on the the `t` function:

* [essentials](https://www.i18next.com/translation-function/essentials.html)
* [interpolation](https://www.i18next.com/translation-function/interpolation.html)
* [formatting](https://www.i18next.com/translation-function/formatting.html)
* [plurals](https://www.i18next.com/translation-function/plurals.html)
  {% endhint %}

## Samples

### Using with React components

For use cases where you need to embed React components into your translations, `IcuTrans` can be used.

This component enables you to nest any React content to be translated as one cohesive string. It supports both plural and interpolation. The `<Trans>` component will automatically use the most relevant `t()` function (from the [context instance](https://react.i18next.com/latest/i18nextprovider) or the global instance), unless overridden via the `i18n` or `t` props.

*Let's say you want to create following HTML output:*

> Hello **Arthur**, you have 42 unread messages. [Go to messages](https://github.com/i18next/react-i18next-gitbook/blob/master/legacy-v9/trans-component.md).

**Before:** Your untranslated React code would have looked something like:

```javascript
function MyComponent({ person, messages }) {
  const { name } = person;
  const count = messages.length;

  return (
    <>
      Hello <strong title="This is your name">{name}</strong>, you have {count} unread message(s). <Link to="/msgs">Go to messages</Link>.
    </>
  );
}
```

**After:** With the IcuTrans component change it to:

{% tabs %}
{% tab title="JavaScript" %}

```jsx
import { IcuTrans } from 'react-i18next';

function MyComponent({ person, messages }) {
  const { name } = person;
  const count = messages.length;

  return (
    <IcuTrans
      i18nKey="userMessagesUnread" // optional -> fallbacks to defaults if not provided
      defaultTranslation="hello <0>{{name}}</0>, you have {{count}} unread message. <1>Go to messages</1>."
      values={{ name, count }}
      content={[
        {
          type: "strong",
          props: {
            title: t('nameTitle'),
          },
        },
        {
          type: Link,
          props: {
            to: "/msgs",
          },
        },
      ]}
    />
  );
}
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
import { IcuTrans } from 'react-i18next';

function MyComponent({ person, messages }) {
  const { name } = person;
  const count = messages.length;

  return (
    <IcuTrans
      i18nKey="userMessagesUnread" // optional -> fallbacks to defaults if not provided
      defaultTranslation="hello <0>{{name}}</0>, you have {{count}} unread message. <1>Go to messages</1>."
      values={{ name, count }}
      content={[
        {
          type: "strong",
          props: {
            title: t(($) => $.nameTitle),
          },
        },
        {
          type: Link,
          props: {
            to: "/msgs",
          },
        },
      ]}
    />
  );
}
```

{% endtab %}
{% endtabs %}

*Your en.json (translation strings) will look like:*

```javascript
"nameTitle": "This is your name",
"userMessagesUnread_one": "Hello <1>{{name}}</1>, you have {{count}} unread message. <5>Go to message</5>.",
"userMessagesUnread_other": "Hello <1>{{name}}</1>, you have {{count}} unread messages.  <5>Go to messages</5>.",
```

## IcuTrans props

`defaultTranslation` and `contents` are required properties, all others are optional. You'll need to use `i18nKey` if you're not using natural language keys (text-based).

| ***name***           | ***type (default)***   | ***description***                                                                                                                                                                                                                                                                                                                                                                                                                |
| -------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `i18nKey`            | `string (undefined)`   | <p>If you prefer to use text as keys you can omit this, and the translation will be used as key. Can contain the namespace by prepending it in the form <code>'ns:key'</code> (depending on <code>i18next.options.nsSeparator</code>)</p><p>But this is not recommended when used in combination with natural language keys, better use the dedicated ns parameter: <code>\<Trans i18nKey="myKey" ns="myNS">\</Trans></code></p> |
| `ns`                 | `string (undefined)`   | Namespace to use. May also be embedded in `i18nKey` but not recommended when used in combination with natural language keys, see above.                                                                                                                                                                                                                                                                                          |
| `t`                  | `function (undefined)` | `t` function to use instead of the global `i18next.t()` or the `t()` function provided by the nearest [provider](https://react.i18next.com/latest/i18nextprovider).                                                                                                                                                                                                                                                              |
| `count`              | `integer (undefined)`  | Numeric value for pluralizable strings                                                                                                                                                                                                                                                                                                                                                                                           |
| `context`            | `string (undefined)`   | Value used for the [context feature](https://www.i18next.com/translation-function/context).                                                                                                                                                                                                                                                                                                                                      |
| `tOptions`           | `object (undefined)`   | Extra options to pass to `t()` (e.g. `context`, `postProcessor`, ...)                                                                                                                                                                                                                                                                                                                                                            |
| `parent`             | `node (undefined)`     | A component to wrap the content into (can be globally set on `i18next.init`). **Required for React < v16**                                                                                                                                                                                                                                                                                                                       |
| `i18n`               | `object (undefined)`   | i18next instance to use if not provided by context                                                                                                                                                                                                                                                                                                                                                                               |
| `defaultTranslation` | `string`               | Use this instead of using the children as default translation value (useful for ICU)                                                                                                                                                                                                                                                                                                                                             |
| `values`             | `object (undefined)`   | Interpolation values                                                                                                                                                                                                                                                                                                                                                                                                             |
| `contents`           | `array[TypeDef]`       | Components to interpolate based on index of tag. This should be either `{ type: ComponentFunction }` or for built-in DOM elements `{ type: "a" }`, for example. `props` can be used to pass props to the component `{ type: "a", props: { href="/somewhere" } }`                                                                                                                                                                 |
| `shouldUnescape`     | `boolean (false)`      | HTML encoded tags like: `&lt; &amp; &gt;` should be unescaped, to become: `< & >`                                                                                                                                                                                                                                                                                                                                                |

### i18next options

```javascript
i18next.init({
  // ...
  react: {
    // ...
    hashTransKey: function(defaultValue) {
      // return a key based on defaultValue or if you prefer to just remind you should set a key return false and throw an error
    },
    defaultTransParent: 'div', // a valid react element - required before react 16
    transEmptyNodeValue: '', // what to return for empty Trans
    transSupportBasicHtmlNodes: true, // allow <br/> and simple html elements in translations
    transKeepBasicHtmlNodesFor: ['br', 'strong', 'i'], // don't convert to <1></1> if simple react elements
    transWrapTextNodes: '', // Wrap text nodes in a user-specified element.
                            // i.e. set it to 'span'. By default, text nodes are not wrapped.
                            // Can be used to work around a well-known Google Translate issue with React apps. See: https://github.com/facebook/react/issues/11538
                            // (v11.10.0)
  }
});
```

{% hint style="warning" %}
Please be aware if you are using **React 15 or below**, you are required to set the `defaultTransParent` option, or pass a `parent` via props.
{% endhint %}

{% hint style="danger" %}
**Are you having trouble when your website is ran through Google Translate?**\
Google Translate seems to manipulate the DOM and makes React quite unhappy!\
**There's a work around:** you can wrap text nodes with`<span>` using `transWrapTextNodes: 'span'`.

*If you want to know more about the Google Translate issue with React, have a look at* [*this*](https://github.com/facebook/react/issues/11538#issuecomment-390386520)*.*
{% endhint %}


# I18nextProvider

## What it does

The I18nextProvider does take an i18next instance via prop i18n and passes that down using the context API.

```jsx
import { I18nextProvider } from 'react-i18next';
import i18n from './i18n';
import App from './App';

<I18nextProvider i18n={i18n} defaultNS={'translation'}>
  <App />
</I18nextProvider>
```

## When to use?

You will need to use the provider if you need to support multiple i18next instances - eg. if you provide a component library ([like this example](https://github.com/i18next/react-i18next/tree/master/example/react-component-lib)) or in scenarios for [SSR (ServerSideRendering)](/latest/ssr). Additionally, you have the ability to manage the default namespace(s) by passing defaultNS.

## I18nextProvider props

| ***name***    | **type (*****default)***        | ***description***                                                                         |
| ------------- | ------------------------------- | ----------------------------------------------------------------------------------------- |
| **i18n**      | object (undefined)              | pass i18next instance the provider will pass it down to translation components by context |
| **defaultNS** | string \| string\[] (undefined) | pass defaultNS to manage the default namespace(s)                                         |


# SSR (additional components)

## Using [Next.js](https://nextjs.org/)?

You should have a look at [next-i18next](https://github.com/i18next/next-i18next) which extends react-i18next to bring it to Next.js the easiest way.

Since `next-i18next@v16`, both **App Router** and **Pages Router** are supported within a single package — no boilerplate needed. The library provides `getT()` for Server Components, `useT()` for Client Components, and automatic language detection via proxy/middleware.

> [Here](https://www.locize.com/blog/next-i18next-v16/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=latest_ssr) you can read about all the improvements in next-i18next v16.
>
> [Here](https://github.com/locize/next-i18next-locize) you can also find a next-i18next app example in combination with locize.
>
> **Looking for an optimized Next.js translations setup?**\
> [Here](https://www.locize.com/blog/next-i18next/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=latest_ssr) you'll find a blog post on how to best use next-i18next with client side translation download and SEO optimization.
>
> [![](/files/sjfxTwvThpPoxIhZEX0O)](https://www.locize.com/blog/next-i18next/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=latest_ssr)
>
> ***
>
> **Using SSG / `next export`?**\
> [Here](https://www.locize.com/blog/next-i18n-static/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=latest_ssr) you'll find a simple tutorial on how to best use next-i18next in a SSG environment.\
> [<img src="/files/nnIRnNN8lMTLOPUQ5ZYU" alt="" data-size="original">](https://www.locize.com/blog/next-i18n-static/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=latest_ssr)

## Using [Remix](https://remix.run)?

You should have a look at [remix-i18next](https://github.com/sergiodxa/remix-i18next) which extends react-i18next to bring it to Remix the easiest way.

> [Here](https://github.com/locize/locize-remix-i18next-example) you'll find a simple example and [here a step by step tutorial](https://www.locize.com/blog/remix-i18n/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=latest_ssr) on how to best use remix-i18next.
>
> [![](/files/yy5kBEi2hrvbFO8tWP2y)](https://www.locize.com/blog/remix-i18n/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=latest_ssr)

## Using [Gatsby](https://www.gatsbyjs.com/)?

You should have a look at [gatsby-plugin-react-i18next](https://github.com/microapps/gatsby-plugin-react-i18next) which extends react-i18next to bring it to Gatsby the easiest way.

> [Here](https://github.com/locize/locize-gatsby-example) you'll find a simple example and [here a step by step tutorial](https://www.locize.com/blog/gatsby-i18n/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=latest_ssr) on how to best use [gatsby-plugin-react-i18next](https://github.com/microapps/gatsby-plugin-react-i18next).
>
> [![](/files/iBmQJsLem8puRKYir5Z0)](https://www.locize.com/blog/gatsby-i18n/?utm_source=react_i18next_com\&utm_medium=gitbook\&utm_campaign=latest_ssr)

## Setting the i18next instance based on req

Use the [I18nextProvider](/latest/i18nextprovider) to inject the i18next instance for example bound to the http i18n instance on the request object using [i18next-http-middleware](https://github.com/i18next/i18next-http-middleware).

```jsx
<I18nextProvider i18n={req.i18n}>
  <App />
</I18nextProvider>
```

## Passing initial translations / initial language down to client

To avoid asynchronous loading of translation on the client side (and the possible Suspense out of that) you will need to pass down initialLanguage (will call changeLanguage on i18next) and initialI18nStore (will prefill translations in i18next store).

### using the useSSR hook

```jsx
import React from 'react';
import { useSSR } from 'react-i18next';

export function InitSSR({ initialI18nStore, initialLanguage }) {
  useSSR(initialI18nStore, initialLanguage);

  return <App />
}
```

### using the withSSR HOC

```jsx
import React from 'react';
import { withSSR } from 'react-i18next';
import App from './App';

const ExtendedApp = withSSR()(App);

<ExtendedApp initialLanguage={} initialI18nStore={} />
```

The ExtendedApp in this case will also have the composed `ExtendedApp.getInitialProps()`


# Migrating v9 to v10

v10 is a complete rewrite, taking the chance to clean up some complexity added from v1 to v9.

This means you will need to test your application more cautiously before release.

{% hint style="info" %}
This is a specific migration guide regarding the complete react-i18next rewrite in v10.\
If you're looking for general release notes, please have a look in the [CHANGELOG](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md) file.
{% endhint %}

## New in v10

The most obvious change is the hook function for use inside functional components:

```jsx
import React from 'react';
import { useTranslation } from 'react-i18next';

export function MyComponent() {
  const [t, i18n] = useTranslation();

  return <p>{t('my translated text')}</p>
}
```

## Components without replacement

The Interpolation component (which was marked as deprecated for a long time and replaced by the Trans Component) was removed finally. You will need to replace it with the Trans Component.

## Migration

Replace your components like described below. If you don't have to use `Suspense` in your existing App you can set `useSuspense: false` in react.init options.react:

```javascript
i18n.init({
  react: {
    useSuspense: false
  }
});
```

## I18nextProvider changes

The `I18nextProvider` no longer provides as many properties as before. Make the necessary changes in your codebase after migrating.

```javascript
// New props
{
  i18n,
  defaultNS,
}

// Old props
{
  i18n,
  defaultNS,
  reportNS,
  lng: i18n && i18n.language,
  t: i18n && i18n.t.bind(i18n),
}
```

## Components v9 -> v10

| Type                | <= v7 (v8)         | v9 (v8)            | v10              |
| ------------------- | ------------------ | ------------------ | ---------------- |
| hook                |                    | -                  | useTranslation   |
| HOC                 | translate          | withNamespaces     | withTranslation  |
| render prop         | I18n               | NamespacesConsumer | Translation      |
| i18next plugin      | reactI18nextModule | reactI18nextModule | initReactI18next |
| Provider            | I18nextProvider    | I18nextProvider    | I18nextProvider  |
| Complex Translation | Trans              | Trans              | Trans            |
| Interpolations      | Interpolate        | Interpolate        | Trans            |


# TypeScript

{% hint style="warning" %}
Make sure you update to **react-i18next >= 13.0.0** and **i18next >= 23.0.1** and follow the instructions [here](https://www.i18next.com/overview/typescript).
{% endhint %}


# Using with ICU format

i18next itself is flexible enough to support multiple existing i18next formats beside its own. So also the ICU format, thanks to [i18next-icu](https://github.com/i18next/i18next-icu).

{% hint style="info" %}
Find the full working sample [here](https://github.com/i18next/react-i18next/tree/master/example/react-icu).
{% endhint %}

![](/files/-LIeYNAt0tyLaBiaeOVa)

## Extend the i18n instance with ICU module

To enable ICU format you will need to include the [i18next-icu](https://github.com/i18next/i18next-icu) module into your [i18next instance](/latest/i18next-instance).

```javascript
import i18n from 'i18next';
import ICU from 'i18next-icu';
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
import { initReactI18next } from 'react-i18next';

i18n
  .use(ICU)
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: 'en',
    debug: true,

    interpolation: {
      escapeValue: false, // not needed for react!!
    },

    // react i18next special options (optional)
    // react: {
    //   useSuspense: true
    // }
  });


export default i18n;
```

## Use the ICU format

### using t function

{% tabs %}
{% tab title="JavaScript" %}

```jsx
import React from 'react';
import { useTranslation } from 'react-i18next';

function MyComponent() {
  const { t, i18n } = useTranslation();
  // or const [t, i18n] = useTranslation();

  return <div>{t('icu', { numPersons: 500 })}</div>
}

// ...

// json
"icu": "{numPersons, plural, =0 {no persons} =1 {one person} other {# persons}}",

// result:
<div>500 persons</div>
```

{% endtab %}

{% tab title="TypeScript" %}

```tsx
import React from 'react';
import { useTranslation } from 'react-i18next';

function MyComponent() {
  const { t, i18n } = useTranslation();
  // or const [t, i18n] = useTranslation();
  
  return <div>{t($ => $.icu, { numPersons: 500 })}</div>
}

// ...

// json
"icu": "{numPersons, plural, =0 {no persons} =1 {one person} other {# persons}}",

// result:
<div>500 persons</div>
```

{% endtab %}
{% endtabs %}

### using the Trans Component

{% hint style="warning" %}
Warning: direct use of `Trans` (not using the `icu.macro` babel macro) may not be compatible with [`react-compiler`](https://react.dev/learn/react-compiler). Use the `IcuTrans` component or the `icu.macro` babel macro instead.
{% endhint %}

Using ICU syntax is not possible within a JSX node because `{curly brackets}` are reserved for interpolation.

To work around this, you can use the [IcuTrans Component](/latest/icu-trans-component) directly like this:

```javascript
import { IcuTrans } from 'react-i18next';

const user = 'John Doe';

<IcuTrans
  i18nKey="icu_and_trans"
  defaultTranslation="We invited <0>{user}</0>."
  content={[{ type: "strong" }]}
  values={{ user }}
/>

// json
"icu_and_trans": "We invited <0>{user}</0>."

// result
We invited <strong>John Doe</strong>.
```

While this works the resulting JSX is very verbose and prone to errors. Let's use a babel macro to provide more intuitive syntax!

### using babel macros (Trans, Plural, Select)

{% hint style="info" %}
Thanks to using [kentcdodds/babel-plugin-macros](https://github.com/kentcdodds/babel-plugin-macros) we could use some babel magic to transpile nicer looking jsx to above Trans markup.

Check <https://github.com/kentcdodds/babel-plugin-macros/blob/master/other/docs/user.md> for setting babel-plugin-macros up.

Using create-react-app? Make sure you are using react-scripts v2 as it includes the macro plugin.

```
$ # Create a new application
$ npx create-react-app
$ # Upgrade an existing application
$ yarn upgrade react-scripts@2
```

{% endhint %}

```javascript
import { Trans } from 'react-i18next/icu.macro';

const user = 'John Doe';

<Trans i18nKey="icu_and_trans">
  We invited <strong>{user}</strong>.
</Trans>
```

The macro will add the needed import for the `IcuTrans` Component and generate the correct `IcuTrans` component for you.

The correct string for translations will be shown in the browser console output as a missing string (if set debug: true on i18next init) or submitted via saveMissing (have saveMissing set true and a i18next backend supporting saving missing keys).

The defaults parsing supports the `@babel/react` preset, so any expressions that require more complex parsing may not work.

**More samples:**

```jsx
// basic interpolation
<Trans>Welcome, { name }!</Trans>

// interpolation and components
<Trans>Welcome, <strong>{ name }</strong>!</Trans>
<Trans defaults="Welcome, <strong>{ name }</strong>" />

// number formatting
<Trans>Trainers: { trainersCount, number }</Trans>
<Trans>Trainers: <strong>{ trainersCount, number }</strong>!</Trans>
<Trans defaults="Trainers: <strong>{ trainersCount, number }</strong>!" />

// date formatting
<Trans>Caught on { catchDate, date, short }</Trans>
<Trans>Caught on <strong>{ catchDate, date, short }</strong>!</Trans>
<Trans defaults="Caught on <strong>{ catchDate, date, short }</strong>!" />

<Trans>You have <Link to="/inbox">{ unread, number } messages</Link></Trans>
<Trans defaults="You have <Link to='/inbox'>{ unread, number } messages</Link>" />
```

#### Tagged Template for ICU

To support complex interpolations, `react-i18next` provides additional imports from the `icu.macro`. These provide a way to represent translations closer to the ICU messageformat syntax, but in a manner that is compatible with React and strictly typed in typescript.

For example, to format a number:

```javascript
import { Trans } from "react-i18next/icu.macro";

const num = 1;

<Trans i18nKey="number">
 Incremented {num, number} times
</Trans>
```

the above syntax, although valid javascript, will error when using a linting tool like eslint. Instead, we can do this:

```jsx
import { Trans, number } from "react-i18next/icu.macro";

const num = 1;

<Trans i18nKey="number">
 Incremented {number`${num}`} times
</Trans>
```

This results in the translation string `Incremented {num, number} times`

Supported interpolators are `number`, `date`, `time`, `select`, `plural`, and `selectOrdinal`.

More complex skeletons can also be represented:

```jsx
import { Trans, number } from "react-i18next/icu.macro";

const awesomePercentage = 100;

<Trans i18nKey="number">
 It's awesome {number`${awesomePercentage}, ::percent`} of the time
</Trans>
```

This results in the translation string `It's awesome {awesomePercentage, number, ::percent} of the time`.

**Complex interpolations with plural/select/selectOrdinal**

The `plural` and `select` and `selectOrdinal` interpolations support more advanced syntax. For instance, it is possible to interpolate both React elements and other interpolations:

```jsx
import { Trans, plural, number } from "react-i18next/icu.macro";

const awesomePercentage = 100;

<Trans i18nKey="number">
 {plural`${awesomePercentage},
   =0 { It's ${<i>never</i>} awesome }
   =100 { It is ${<b>ALWAYS</b>} awesome! }
   other { It's awesome {number`${awesomePercentage}, ::percent`} of the time }`}
</Trans>
```

This will result in the translation string `{awesomePercentage, plural, =0 { It's <0>never&lt;/0&gt; awesome } =100 { It is <1>ALWAYS&lt;/1&gt; awesome! } =100 { It's awesome {awesomePercentage, number, ::percent} of the time }}`

It possible to nest any interpolated type, including nested `plural`, `select`, or `selectOrdinal`.

**Typescript support for interpolated template strings**

The `number`, `plural`, and `selectOrdinal` functions will error if a non-number typed variable is interpolated.

```jsx
import { Trans, number } from "react-i18next/icu.macro";

// type error below - awesomePercentage must be a number
const awesomePercentage = "100";

<Trans i18nKey="number">
 It's awesome {number`${awesomePercentage}, ::percent`} of the time
</Trans>
```

The `date` and `time` functions will error if a non-Date object is interpolated.

```jsx
import { Trans, date } from "react-i18next/icu.macro";

// type error below - awesomePercentage must be a number
const notADate = "100";

<Trans i18nKey="number">
 What time is it? it's {date`${notADate}`} o'clock
</Trans>
```

Finally, the `select` function will error if a non-string is interpolated.

```jsx
import { Trans, select } from "react-i18next/icu.macro";

// type error below - awesomePercentage must be a number
const notAString = 100;

<Trans i18nKey="number">
 {select`${notAString} oops { you have to pass in a string } other { oh well }`}
</Trans>
```

### Alternative syntax for select and plural

It is also possible to display `select` and `plural` and `selectOrdinal` using Elements `Select`, `Plural` and `SelectOrdinal`. All of them have full type safety in typescript.

#### Select

There is no way to directly add the needed ICU format inside a JSX child - so we had to add another component that gets transpiled to needed Trans component:

```jsx
import { Select } from 'react-i18next/icu.macro';

// simple select
<Select
  i18nKey="optionalKey" // optional key
  switch={gender}
  male="He avoids bugs."
  female="She avoids bugs."
  other="They avoid bugs."
/>
```

```jsx
import { Select } from 'react-i18next/icu.macro';

// select with inner components
<Select
  i18nKey="optionalKey" // optional key
  switch={gender}
  male={<Trans><strong>He</strong> avoids bugs.</Trans>}
  female={<Trans><strong>She</strong> avoids bugs.</Trans>}
  other={<Trans><strong>They</strong> avoid bugs.</Trans>}
/>
```

#### Plural

```jsx
import { Plural } from 'react-i18next/icu.macro';

// simple plural
<Plural
  i18nKey="optionalKey" // optional key
  count={itemsCount}
  $0="There is no item."
  one="There is # item."
  other="There are # items."
/>
```

```jsx
import { Plural } from 'react-i18next/icu.macro';

// plural with inner components
<Plural
  i18nKey="optionalKey" // optional key
  count={itemsCount3}
  $0={<Trans>There is <strong>no</strong> item.</Trans>}
  one={<Trans>There is <strong>#</strong> item.</Trans>}
  other={<Trans>There are <strong>#</strong> items.</Trans>}
/>
```

#### SelectOrdinal

```jsx
import { SelectOrdinal } from 'react-i18next/icu.macro';

// simple SelectOrdinal
<SelectOrdinal
  i18nKey="optionalKey"
  count={position}
  one="You are #st in line"
  two="You are #nd in line"
  few="You are #rd in line"
  other="You are #th in line"
/>
```

```jsx
import { SelectOrdinal } from 'react-i18next/icu.macro';

// SelectOrdinal with inner components
<SelectOrdinal
  i18nKey="optionalKey"
  count={position}
  one={<Trans>You are <strong>#st in line</strong></Trans>}
  two={<Trans>You are <strong>#nd in line</strong></Trans>}
  few={<Trans>You are <strong>#rd in line</strong></Trans>}
  other={<Trans>You are <strong>#th in line</strong></Trans>}
  $7={<Trans>You are the lucky <strong>#th in line</strong></Trans>}
/>
```

{% hint style="info" %}
The needed plural forms can be looked up in the official unicode cldr table: <http://www.unicode.org/cldr/charts/33/supplemental/language_plural_rules.html>

In addition to the plural forms you can specify results for given number values like show above:

`0="show if zero"`

in ICU it would be `=0 {show if zero}` but `=` is not allowed to be leading char in attributes so we replaced it with `$`
{% endhint %}


# Using with fluent format

i18next itself is flexible enough to support multiple existing i18next formats beside it's own.

{% hint style="info" %}
Find the full working sample here:

<https://github.com/i18next/react-i18next/tree/master/example/react-fluent>
{% endhint %}


# Testing

For testing purpose of your component you should export the pure component without extending with the withTranslation hoc and test that:

```javascript
export MyComponent;
export default withTranslation('ns')(MyComponent);
```

In the test, test the myComponent export passing a t function mock:

```javascript
import { MyComponent } from './myComponent';

<MyComponent t={key => key} />
```

Or create a manual mock in `__mocks__/react-i18next.js` (picked up automatically by jest) that covers `useTranslation`, `withTranslation` and `<Trans>` in one place, so components mixing all three render their keys and children as plain text:

```jsx
const React = require('react');
const reactI18next = require('react-i18next');

const useMock = [(k) => k, { changeLanguage: () => new Promise(() => {}) }];
useMock.t = (k) => k;
useMock.i18n = { changeLanguage: () => new Promise(() => {}) };

module.exports = {
  ...reactI18next,
  withTranslation: () => (Component) => (props) => <Component t={(k) => k} {...props} />,
  Trans: ({ children, i18nKey }) => children ?? i18nKey,
  useTranslation: () => useMock,
};
```

A more complete version of this mock (including a `<Trans>` mock that renders nested elements) is part of the runnable jest example: [example/test-jest/src/\_\_mocks\_\_/react-i18next.js](https://github.com/i18next/react-i18next/blob/master/example/test-jest/src/__mocks__/react-i18next.js)

Or mock it like:

```javascript
jest.mock('react-i18next', () => ({
  // this mock makes sure any components using the translate HoC receive the t function as a prop
  withTranslation: () => Component => {
    Component.defaultProps = { ...Component.defaultProps, t: (i18nKey) => i18nKey };
    // or with TypeScript:
    //Component.defaultProps = { ...Component.defaultProps, t: (i18nKey: string) => i18nKey };
    return Component;
  },
}));
```

Or, when using the `useTranslation` hook instead of `withTranslation`, mock it like:

```javascript
jest.mock('react-i18next', () => ({
  // this mock makes sure any components using the translate hook can use it without a warning being shown
  useTranslation: () => {
    return {
      t: (i18nKey) => i18nKey,
      // or with TypeScript:
      //t: (i18nKey: string) => i18nKey,
      i18n: {
        changeLanguage: () => new Promise(() => {}),
      },
    };
  },
  initReactI18next: {
    type: '3rdParty',
    init: () => {},
  }
}));
```

or, you can also spy the `t` function:

{% tabs %}
{% tab title="JavaScript" %}

<pre class="language-jsx"><code class="lang-jsx"><strong>// implementation
</strong>import React from 'react';
import { useTranslation } from 'react-i18next';

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

  return &#x3C;div>{t('some.key', { some: 'variable' })}&#x3C;/div>;
}

<strong>// test
</strong>import React from 'react';
import { render, screen } from '@testing-library/react';
import UseTranslationWithInterpolation from './UseTranslationWithInterpolation';
import { useTranslation } from 'react-i18next';

jest.mock('react-i18next', () => ({
  useTranslation: jest.fn(),
}));

it('test render', () => {
  const useTranslationSpy = useTranslation;
  const tSpy = jest.fn((str) => str);
  useTranslationSpy.mockReturnValue({
    t: tSpy,
    i18n: {
      changeLanguage: () => new Promise(() => {}),
    },
  });

  render(&#x3C;UseTranslationWithInterpolation />);

  expect(screen.getByText('some.key')).toBeInTheDocument();

  // If you want you can also check how the t function has been called,
  // but basically this is testing your mock and not the actual code.
  expect(tSpy).toHaveBeenCalledTimes(1);
  expect(tSpy).toHaveBeenLastCalledWith('some.key', { some: 'variable' });
});
</code></pre>

{% endtab %}

{% tab title="TypeScript" %}

<pre class="language-tsx"><code class="lang-tsx"><strong>// implementation
</strong>import React from 'react';
import { useTranslation } from 'react-i18next';

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

  return &#x3C;div>{t($ => $.some.key, { some: 'variable' })}&#x3C;/div>;
}

<strong>// test
</strong>import React from 'react';
import { render, screen } from '@testing-library/react';
import UseTranslationWithInterpolation from './UseTranslationWithInterpolation';
import { useTranslation } from 'react-i18next';

jest.mock('react-i18next', () => ({
  useTranslation: jest.fn(),
}));

it('test render', () => {
  const useTranslationSpy = useTranslation;
  const tSpy = jest.fn((str) => str);
  useTranslationSpy.mockReturnValue({
    t: tSpy,
    i18n: {
      changeLanguage: () => new Promise(() => {}),
    },
  });

  render(&#x3C;UseTranslationWithInterpolation />);

  expect(screen.getByText('some.key')).toBeInTheDocument();

  // If you want you can also check how the t function has been called,
  // but basically this is testing your mock and not the actual code.
  expect(tSpy).toHaveBeenCalledTimes(1);
  expect(tSpy).toHaveBeenLastCalledWith('some.key', { some: 'variable' });
});
</code></pre>

{% endtab %}
{% endtabs %}

{% hint style="success" %}
You can find a full sample for testing with jest here: <https://github.com/i18next/react-i18next/tree/master/example/test-jest>
{% endhint %}

## Testing without stubbing

Alternatively, you could also test I18next without stubbing anything, by providing the correct configuration and fully wrapping your container in the provider.

### Example configuration for testing

```javascript
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

i18n
  .use(initReactI18next)
  .init({
    lng: 'en',
    fallbackLng: 'en',

    // have a common namespace used around the full app
    ns: ['translationsNS'],
    defaultNS: 'translationsNS',

    debug: true,

    interpolation: {
      escapeValue: false, // not needed for react!!
    },

    resources: { en: { translationsNS: {} } },
  });

export default i18n;
```

### Example test using this configuration

```javascript
import React from 'react';
import { Provider } from 'react-redux';
import { render, fireEvent } from '@testing-library/react';
import { I18nextProvider } from 'react-i18next';
import configureStore from 'redux-mock-store';
import ContactTable from './ContactTable';
import actionTypes from '../constants';
import i18n from '../i18nForTests';

const mockStore = configureStore([]);
const store = mockStore({ contacts: [ ] });

it('dispatches SORT_TABLE', () => {
  const { container } = render(
    <Provider store={store}>
      <I18nextProvider i18n={i18n}>
        <ContactTable />
      </I18nextProvider>
    </Provider>
  );
  fireEvent.click(container.querySelector('.sort'));
  const actions = store.getActions();
  expect(actions).toEqual([{ type: actionTypes.SORT_TABLE }]);
});
```

As translations aren't provided, `this.props.i18n.language` will be `undefined`. In case your application relies on that value you can mock resources by adding these lines to the object passed to init:

```
i18n
  .init({
    ...
    fallbackLng: 'en',
    resources: {
      en: {},
      de: {}
    }
  })
```

Now in your component `this.props.i18n.language` will return `en`.


