HTML tags in i18next translation files in React

Don’t put the HTML tags in the translation. It’s a bad idea anyway. Separation of concerns guys will be all whiny about it.

Use the <Trans> component if react-i18next https://react.i18next.com/latest/trans-component

Do like so:

// Component.js

<Trans>Welcome, <strong>User!</strong>, here's your <strong>broom</strong></Trans>

And the corresponding translation file:

// your locales/starwars_en.js file

translations: {
  "Welcome, <1>User!</1>, here's your <3>broom</3>": "Welcome, <1>young padawan!</1>, here's your <3>light saber</3>",
}

These numbers <1> and <3> will strike you as random but wait for it:

Trans.children = [
  'Welcome, ',                        // index 0
  '<strong>User!</strong>'            // index 1
  ', please don't be ',               // index 2
  '<strong>weak</strong>',            // index 3
  ' unread messages. ',               // index 4
]

SIDE NOTE (Can be considered a hack but saves tons of time): The guys at react.i18next.com, don’t have this in their docs, but you can use the base language as a key (English in this case). It saves you time, not to double translate like they showed in their docs and I quote:

// Component file

import React from 'react';
import { Trans } from 'react-i18next'

function MyComponent({ person, messages }) {
  const { name } = person;
  const count = messages.length;

  return (
    <Trans i18nKey="userMessagesUnread" count={count}>
      Hello <strong title={t('nameTitle')}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
    </Trans>
  );
}
// translation file

"userMessagesUnread": "Hello <1>{{name}}</1>, you have {{count}} unread message. <5>Go to message</5>.",
"userMessagesUnread_plural": "Hello <1>{{name}}</1>, you have {{count}} unread messages.  <5>Go to messages</5>.",

Anyway “Kudos!” to the i18next team! You are awesome, guys!

Here – go nuts!

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)