I'm using i18next in a project and can't get around including html tags in translation files and having them properly rendered.
An example of my .json
translation file:
"en": {
"product": {
"header": "Welcome, <strong>User!</strong>"
}
}
There is an excellent answer to this question, but relating to JQuery. I'm not using JQuery, my project is React and here is the setup that I have:
import i18next from 'i18next';
import en from 'locales/en';
i18next.
init({
lng: 'en',
fallbackLng: false,
resources: en,
debug: false,
interpolation: {
escapeValue: false
}
});
export default i18next.t.bind(i18next);
In component I have:
import t from 'i18n';
t('product.header')
Html that I want:
Welcome, <strong>User!</strong>
Html I'm getting:
Welcome, <strong>User!</strong>
Thanks
Based on the React i18n framework, react-i18next is another popular internationalization library which uses components to render or re-render the translated content of your application once users request a change of language.
The easiest way to internationalize a React app is to use the library i18next. i18next is an internationalization framework written in Javascript that can be used with many languages and frameworks, but most importantly with 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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With