reactjsi18nextreact-i18next

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

  • 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