Skip to main content

Interpolation

localize-react uses literal {{double-mustache}} tokens for substitutions.

const messages = { en: { hello: 'Hi {{name}}, you have {{count}} new mail.' } };

translate('hello', { name: 'Alex', count: 3 });
// → "Hi Alex, you have 3 new mail."

What's a valid token?​

The pattern is /\{\{([^{}]+)\}\}/g — anything between {{ and }} that doesn't itself contain a brace.

InputToken?
{{name}}✅
{{ name }}✅ (key is name — note the spaces)
{{a.b.c}}✅ (key is the literal string a.b.c)
{{{a}}}Only {{a}} matches. The outer braces stay.
{name}❌

Prefer simple, unspaced keys: {{name}}, {{count}}, {{total}}.

Values​

values is a Record<string, string | number>. Numbers are coerced via String() at render time. Anything else is a type error.

translate('cart.summary', { count: 3 }); // ok
translate('cart.summary', { count: '3' }); // ok
translate('cart.summary', { count: true }); // ❌ type error
translate('cart.summary', { count: null }); // ❌ type error

That keeps the rendered output predictable.

Regex-meta safety​

Interpolation uses String.prototype.replaceAll(token, value) — a literal replacement, not new RegExp(token).replace(...). So values containing regex meta-characters ($&, $1, etc.) render as-is, with no surprise expansion:

translate('out', { x: '$&' }, '{{x}}');
// → "$&" (not the entire matched substring)

Missing values​

If a {{token}} appears in the resolved string but no matching key is in values, the token is kept verbatim and a console.warn is logged:

[LOCALIZE-REACT] Looks like template is being used, but no value passed for {{name}}

That's intentional — silent identity replacement masks bugs.

Memoization caveat​

The internal cache key includes JSON.stringify(values). If your values object has stable shape and ordering, cache hits will be common. If you pass freshly-allocated values with random ordering on every render, you'll miss the cache (but it stays correct — never wrong, just slower).