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 filetranslations: { "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 fileimport 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!
not a problem of react-i18next - you just can't add html into a react element. react will safe you from xss vulnerability and escape the content:
more detail and possible solution: https://facebook.github.io/react/tips/dangerously-set-inner-html.html
but be aware if you put user content there not escaped you open your site to xss attacks.
more secure reading the react-i18next readme: https://github.com/i18next/react-i18next#interpolate-component
which makes you split content
so the "best" solution - at least what we do - is using markdown in the translations and use eg: https://github.com/acdlite/react-remarkable to convert that to formatted content.
Since react-i18next@11.6.0
, you can use tags inside your translation string and replace it with component
prop in Trans
component or t
property from useTranslation
hook:
Example of usage:
<Trans i18nKey="myKey" // optional -> fallbacks to defaults if not provided defaults="hello <italic>beautiful</italic> <bold>{{what}}</bold>" // optional defaultValue values={{ what: 'world'}} components={{ italic: <i />, bold: <strong /> }}/>