---
title: "How do I pass variables into an i18next translation?"
description: "Write the variable as `{{name}}` in the string and pass its value in the options object, `t('welcome', { name })`. In React set `interpolation.escapeValue` to `false`, use `count` for plurals, and `$t(key)` to nest another key."
category: react
date: 2026-10-09
canonical: https://localizely.com/i18n-questions/react/how-do-i-pass-variables-into-an-i18next-translation/
---

# How do I pass variables into an i18next translation?

Mark the variable with double curly braces in the resource and pass the value in the second argument of `t`; dot notation reaches into objects:

```json
{
  "welcome": "Hello {{name}}",
  "author": "Written by {{author.name}}"
}
```

```jsx
const { t } = useTranslation();

t('welcome', { name: 'Ana' });            // Hello Ana
t('author', { author: { name: 'Ana' } }); // Written by Ana
```

By default i18next HTML-escapes every interpolated value (`escapeValue: true`) to prevent XSS where the result is injected with `innerHTML`. React already escapes what it renders, so with react-i18next turn this off in `init`; otherwise a value such as `Tom & Jerry` shows up as `Tom &amp; Jerry`:

```javascript
i18n.use(initReactI18next).init({
  interpolation: { escapeValue: false },
});
```

If you keep escaping on, `{{- name}}` disables it for a single placeholder. With escaping off, never pass unchecked user input into nesting options; the [interpolation docs](https://www.i18next.com/translation-function/interpolation) explain that injection path.

Nesting reuses another key inside a string with `$t(key)`, which is handy for product names and glossary terms:

```json
{
  "product": "Acme Notes",
  "signIn": "Sign in to $t(product)"
}
```

Do not format numbers and dates before passing them. Since i18next 21.3 the built-in [formatters](https://www.i18next.com/translation-function/formatting) based on `Intl` do it per language, with options in parentheses or in `formatParams`:

```json
{
  "total": "Total {{amount, currency(EUR)}}",
  "updated": "Updated on {{date, datetime}}",
  "rating": "{{score, number(maximumFractionDigits: 1)}} out of 5"
}
```

```javascript
t('total', { amount: 1234.5 });              // de: Total 1.234,50 €
t('updated', { date: new Date(2026, 9, 9) }); // de: Updated on 9.10.2026
```

`relativetime` and `list` exist as well. Custom formats are registered with `i18n.services.formatter.add(name, fn)` after `init`; the old `interpolation.format` callback was removed in i18next 26.

Plurals are driven by a variable too: pass `count` and provide one key per CLDR plural category using the JSON v4 suffixes:

```json
{
  "inbox_one": "You have {{count}} new message",
  "inbox_other": "You have {{count}} new messages"
}
```

`t('inbox', { count: 3 })` selects the form through `Intl.PluralRules`, which i18next requires since v24 (React Native on Hermes needs a polyfill). Languages such as Arabic, Russian or Polish also need `_zero`, `_two`, `_few` or `_many`; [Language plural rules](/language-plural-rules/) lists the categories per language. `compatibilityJSON: 'v3'`, which kept old `_plural` keys working, is gone since v24.

Interpolation only produces strings. To put a link or `<strong>` into the sentence you need the `Trans` component instead; [How to add HTML tags to a localization message in React?](/i18n-questions/react/how-to-add-html-tags-to-a-localization-message-in-react/) covers rich text in messages. The react-intl counterpart, ICU `{name}` placeholders with `formatMessage`, is in [How to use dynamic strings in a localization message in React?](/i18n-questions/react/how-to-use-dynamic-strings-in-a-localization-message-in-react/).

Source: https://localizely.com/i18n-questions/react/how-do-i-pass-variables-into-an-i18next-translation/
