Ir al contenido
Sonenta

Guide

Rich text and interpolation

When a translated string carries markup or a value, you render it with <Trans>. It is the only rich-text component in the SDK, and this page is its reference.

The component

Import Trans from @sonenta/react-i18next. Placeholders come from values, tags from components.

Terms.tsx
import { Trans } from "@sonenta/react-i18next";

<Trans
  i18nKey="cta.terms"
  defaults="Hi {{name}}, please accept the <bold>terms</bold>."
  values={{ name: "Marc" }}
  components={{ bold: <strong /> }}
/>

What this actually renders

The output below was not derived from the source, it was produced by running the snippet against version 3.0.0.

output
Hi Marc, please accept the <strong>terms</strong>.

Two ways to map components

Pass an object for named tags (<bold>…</bold>, as above), or an array for numbered slots (<0>…</0> with components={[<strong />]}). Both work. Prefer the named form: it stays readable, and it survives a translator rewording the sentence. The indexed form does not.

Every tag in a string must be mapped

A tag that appears in a translated value but is missing from components does not disappear, and it is not interpreted. It is displayed as literal text, on screen, to your user. Measured on 3.0.0:

Input, with no mapping
'Read this <foreign lang="en">as-is</foreign> please.'
What your user sees on screen
Read this <foreign lang="en">as-is</foreign> please.

This is also the direct answer to a common misreading. Sonenta never inserts markup into your translations, and never interprets any of its own accord. Your strings are stored and delivered as text. <code>&lt;Trans&gt;</code> renders only the tags <strong>you</strong> explicitly mapped through <code>components</code>; every other tag is displayed as literal text, exactly as above.

Keeping the right namespace

Pass the t from the surrounding useTranslation(ns) with <Trans t={t} …>. Without it, the sentence can silently resolve against the default namespace instead of yours.

All <Trans> props

Thirteen props, none of them required. In practice you need i18nKey, plus defaults for as long as the key is not published yet.

Prop Type
i18nKey string
ns string | string[]
namespace string (deprecated, alias of ns)
defaults string
values Record<string, unknown>
components readonly ReactNode[] | Record<string, ReactNode>
count number
context string
tOptions Record<string, unknown>
shouldUnescape boolean
parent unknown (wrapper, or null for a fragment)
t (key: string) => string
children ReactNode

What does not exist

To close the guesswork: there is no <SonentaText> component, and no component of ours takes a fallback prop. <Trans> is the whole rich-text surface. Sonenta never inserts markup into your translations and never interprets any of its own accord: your strings are stored and delivered as text, and <Trans> renders only the tags you map through components.

Verified against @sonenta/react-i18next 3.0.0.

← Back to the React quickstart