# 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)
{% 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](https://react.i18next.com/latest/usetranslation-hook) or [`withTranslation` HOC](https://react.i18next.com/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.

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

> Hello **Arthur**, you have 42 unread messages. [Go to messages](https://react.i18next.com/legacy-v9/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)

## 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 %}
