Robo Robok
Robo Robok

Reputation: 22663

React components in i18next interpolation display as [object Object]

My React app uses next-i18next package. I'd like to put some React component inside my interpolation:

import React from 'react';
import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';

export default function Review({ text, author }) {
  const { t } = useTranslation('reviews');

  return (
    <article>
      <p>{text}</p>
      <footer>
        {t('footer', { author: <a href={author.url}>{author.name}</a> })}
      </footer>
    </article>
  );
}

export const getStaticProps = async ({ locale }) => ({
  props: {
    ...await serverSideTranslations(locale, ['reviews']),
  }
});

And reviews.json:

{
    "footer": "By {{author}}, all rights reserved"
}

Trying to use JSX element to fill the interpolation doesn't work as expected. The result I'm getting is:

By [object Object], all rights reserved

I also tried with unescaped interpolation with By {{- author}}, all rights reserved, but it ends up being the same result.

Can I use JSX element to fill my interpolation?

Upvotes: 6

Views: 3359

Answers (1)

felixmosh
felixmosh

Reputation: 35473

You can't use t function in order to inject jsx.

There is a special Trans component for this, you should use it.

import React from 'react';
import { useTranslation, Trans } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';

export default function Review({ text, author }) {
  const { t } = useTranslation('reviews');

  return (
    <article>
      <p>{text}</p>
      <footer>
        <Trans
          i18nKey="footer"
          t={t}
          values={{ author }}
          components={{ authorLink: <a href={author.url}>placeholder</a> }}
        />
      </footer>
    </article>
  );
}

export const getStaticProps = async ({ locale }) => ({
  props: {
    ...(await serverSideTranslations(locale, ['reviews'])),
  },
});

When in your translation file you will have:

{
  "footer": "My footer text <authorLink>{{author.name}}</authorLink>"
}

Upvotes: 6

Related Questions