quikina
quikina

Reputation: 165

How to use react-i18next <Trans> Component to display array elements?

I am using the following Trans Component to be able to print parts of my text in bold or italic:

<Trans i18nKey="namespace:text" >
   <strong></strong><i></i>
</Trans>

My json looks like this:

"text": "This part should be <0>bold</0> and this one <1>italic</1>.",

"list": [
    "Listelement <1>number</1> one.",
    "This is the <0>second</0> listelement",
    "<0>one</0> more <1>element</1>"
]

For text element this works totally fine. But I also want to print out a list from my json.I usually use the following code snippet:

{this.props.t('namespace:list', {returnObjects:true}).map((item,index) => (
   <li key={index}> {item} </li>
))}

Now I want to use the Trans Component to be able to have bold and italic words in my list aswell. I tried:


{this.props.t('namespace:list', {returnObjects:true}).map((item,index) => (
    <li>
        <Trans i18nKey={"namespace:list."+index} >
             <strong></strong><i></i>
        </Trans>
    </li>
))}

But my list is empty.

How can I use the Component for array elements?

Upvotes: 1

Views: 3231

Answers (2)

simonhenke
simonhenke

Reputation: 11

I used to do it like @felixmosh described as well, however I recently added a missingKeyHandler function to the i18nConfig that logs a warning when there are missing translation keys.

Using the <Trans> component as described above will then log a warning, as the key will not be found in your translation files. What you actually want is to use the <Trans> component solely for interpolation, not for translation. Luckily, it's possible to overwrite the tFunction. Here's a custom component I wrote for that:

interface InterpolateProps {
  value: string;
  components: readonly React.ReactElement[] | { readonly [tagName: string]: React.ReactElement };
}

export const Interpolate: React.FC<InterpolateProps> = ({ value, components }) => {
  return <Trans i18nKey={value} t={(s: string) => s} components={components} />;
};

which can then be used like:

<Interpolate value="Some already translated text with a <Link>Link<Link>" components={{Link: <NextLink href="" />}}/>

Upvotes: 1

felixmosh
felixmosh

Reputation: 35473

You can pass the item it self as i18nKey.

{
  this.props.t('namespace:list', { returnObjects: true }).map((item) => (
    <li>
      <Trans i18nKey={item} components={[<strong />, <em />]} />
    </li>
  ));
}

BTW, it is better to use components prop to pass an array of components.

A working example:

https://codesandbox.io/s/react-i18next-trans-with-list-items-drcei?file=/src/app.js

Upvotes: 5

Related Questions