Response-i18next: Interpolate link in HTML tag in middle of text

I am using react- i18next and react-i18next . I would like to have some translatable text with an HTML link in the middle of the text that 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 that it cannot be hardcoded in the 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 />

      

This seems to be 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} />

      

This might be a solution, however the application has been translated into many languages ​​and the quality of the translations really matters, so I prefer to have all the text on one line for the translators (this is especially important for languages ​​in which there are cases).

Is there a way how to make something like this work (or is there a way how to solve this in a completely different way)?

"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} />

      

+5


source to share


3 answers


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

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

      

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

+5


source


This is a common problem react-intl

and react-i18next

- both libraries have very limited support for built-in components and rich text formatting within translations (I've already covered this here with more details).

If you are still at the start of your project, you may need to consider another i18n library - js-lingui (disclaimer: I am the author). This is the first (and so far the only) library with full support for embedded components.

You just write:



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

      

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

The only cost is you need to use the additional babel plugin, which makes it possible.

0


source


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

was added a few weeks ago and does not allow the insertion of such translations containing html fragments - just know that it is dangerous if the url comes from userinput and contains malicious code (xss attack)

As I can see this was added last year: https://github.com/i18next/react-i18next/pull/195/files

But this will cover by default the range around each part before / after {{link}}, so this may not be what you need ... but the solution is pretty simple - don't use an interpolation component, but regular interpolation on t:

<div dangerouslySetInnerHTML={t('my-label', { link: yourURL }} />

-1


source







All Articles