'React-i18n Trans Component with translations that contain HTML tags not working

I'm trying to use react-i18next with a translation json that contains some HTML tags, like this:

// en.json
{ "welcome": "Welcome to our site, <strong>{{name}}</strong>" }

In my React component, I want the string to be rendered like this.

Welcome to our site, John

Using the useTranslation function normally printed the string literally without interpreting it as HTML, like Welcome to our site, <strong>John</strong>.

import React from 'react'
import { useTranslation } from 'react-i18next'

const App = () => {
  const { t } = useTranslation()

  return(
    <div>{t('welcome', { name: 'John' })}</div>
  )
}

I replaced it with dangerouslySetInnerHTML and it was rendered correctly.

<div dangerouslySetInnerHTML={{ __html: t('welcome', { name: 'John' }) }}></div>

However, I want to avoid using dangerouslySetInnerHTML if possible. I read in the docs that you can use something called Trans components for translations with HTML tags.

Docs: Using for <br /> and other simple html elements in translations (v10.4.0)

But I'm confused about how to use them, since the examples they show seem to be for replacing placeholder tags like <1> with actual tags like <br />. Is there a way to use Trans components (or some other method that doesn't use dangerouslySetInnerHTML) to get translated strings to be interpreted as HTML?

Thanks in advance.



Solution 1:[1]

Yeah, you're doing it wrong.

return (
  <Trans i18nKey="welcome">
    Welcome to our site, <strong>{{name}}</strong>
  </Trans>
)

And your JSON file should look like:

"welcome": "Welcome to our site, <1>{{name}}</1>"

The reason you use <1> is because Trans breaks up your string in to an array, so in this case it's: ["Welcome to our site, ", "<strong>{{name}}</strong>"] https://react.i18next.com/latest/trans-component#how-to-get-the-correct-translation-string

Solution 2:[2]

Posting here because this is the first search result on the interwebz, and none of the answers worked for my case.

My translation JSON looks like this:

"readOnlyField": "<0>{{- key}}:</0> <1>{{- value}}</1>"

The only way I managed to make it work was to use Trans like this:

<Trans
  i18nKey="readOnlyField" // the key in your JSON file
  values={{ // The variables in your i18n entry from the JSON file
    key: "Storage",
    value: "2TB SSD",
  }}
  components={[<strong />, <i />]} // The component at index 0 (<strong />) will be parent of <0> ({{- key}}), and so on...
/>

So it would look like this:

Storage: 2TB SSD

Solution 3:[3]

I just posted an answer to a similar problem i could solve but in React Native, should work in React as well: https://stackoverflow.com/a/70112582/9506908

// render
<Trans i18nKey="yourTranslationKey" components={{ link: <Text onPress={() => console.log('do something')}}} /> }} />

// translationFile
{...
 "yourTranslationKey": "Please <link>Click me</link>",
...}```

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Fappaz
Solution 3 o0bnji0o