Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react-i18next: interpolation of link in HTML tag in the middle of the text

I am using react, i18next and react-i18next. I would like to have some translatable text with HTML link in the middle of the text which is interpolated in react, something like this:

This is my text with <a href="{{link}}">a beautiful link</a> in the middle of the text

The solution below works, but the problem is that I need to interpolate the link in react so it can't be hard-coded in label files:

"my-label": "This is my text with <a href=\"http://google.com\">a beautiful link</a> in the middle of the text"

[...]

<Interpolate i18nKey="my-label" useDangerouslySetInnerHTML />

It seems like this is much better:

"my-label": "This is my text with {{link}} in the middle of the text",
"link" "a beautiful link"

[...]

const { url } = props;
const link = <a href={url}>{t('link')}</a>

<Interpolate i18nKey="my-label" link={link} />

Could be the solution, however the app is translated into many languages and a quality of translations really matters so I prefer to have the whole text in one line for translators (this is important especially for languages which have cases).

Is there any way how to get working something like this (or is there any way how to solve it completely differently)?

"my-label": "This is my text with <a href=\"{{link}}\">a beautiful link</a> in the middle of the text"

[...]

const { url } = props;

<Interpolate i18nKey="my-label" useDangerouslySetInnerHTML link={url} />
like image 567
Knut Holm Avatar asked Apr 24 '17 12:04

Knut Holm


2 Answers

With react-i18next v4.4.0 we introduced a new component Trans:

<Trans i18nKey="optionalKey">See the <Link to="/more">description</Link> below.</Trans>

The json would be: See the <1>description</1> below.

or even more complex:

<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>

The new feature is documented here: https://react.i18next.com/latest/trans-component

like image 89
jamuhl Avatar answered Oct 23 '22 22:10

jamuhl


This is the common problem of react-intl and react-i18next - both libs have very limited support of inline components and rich-text formatting inside translations (I've already described it here with more details).

If you're still at the beginning of your project, you might want to consider different i18n library - js-lingui (disclaimer: I'm the author). It's the first (and so far the only) library with full support for inline components.

You simply write:

<Trans>See the <Link to="/more">description</Link> below.</Trans>

and your translators will work with message See the <0>description</0> below.

The only price is you need to use extra babel plugin, which makes it possible.

like image 24
Tomáš Ehrlich Avatar answered Oct 23 '22 20:10

Tomáš Ehrlich