7

I have a problem with I18next. I can't figure out how to make links to websites work, here is my code:

import React, { Suspense } from "react";
import i18n from "i18next";
import { initReactI18next, useTranslation, Trans } from "react-i18next";

const translationSwe = {
about: "Information",
example: "Exempel <br> <strong>text</strong>, här är <a target='_blank' rel='noreferrer 
noopener' href='https://youtube.com'>länk</a>"
}

const translationEng = {
about: "About"
example: "Example <br> <strong>text</strong>, here is <a target='_blank' rel='noreferrer 
noopener' href='https://youtube.com'>link</a>"
}

i18n.use(initReactI18next).init({
resources: {
swe: { translation: translationSwe },
eng: { translation: translationEng },
},
lng: "swe",
fallbackLng: "swe",
interpolation: { escapeValue: false },
});

const App = () => {
const { t } = useTranslation();

return(
<Suspense fallback="Loading..">
<div className="app">
<p><Trans i18nkey="example"/></p>
</div>
</Suspense>
);
};

Line breaks & strong tags work fine, but link doesn't. Instead of the link it prints just

<a>länk</a>

I have read some articles how to make links work, but in everyone of them data is in seperate JSON files. And in everyone of them you have to also insert the link from where you are calling the Trans component. I would like to just add text(which includes links etc) to translationSwe & translationEng without having to edit Trans component at all later, in case I decide to update or add links. How can I achieve this?

6 Answers 6

3

You're using the Trans component for that, this means you have to write the correct syntax in the translation key:

// key in resources:
keyWithLink: "Hey this is a <1>LINK</1>! Also called <strong>hyperlink</strong>"

used in Trans component:

<Trans i18nKey="keyWithLink">This should be a <a href="https://www.locize.com">some link</a></Trans>

Check out this codesandbox example: https://codesandbox.io/s/react-i18next-example-forked-8y4i0?file=/src/i18n.js:302-383

Sign up to request clarification or add additional context in comments.

Comments

1

You can use dangerouslySetInnerHTML for your translation container (p).

This variant works if you use "t" function

I hope my solution will help you

3 Comments

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
Hey, thank you. It works now, I was just wondering is there risks using dangerouslySetInnerHTML that I should take in consideration when using it with I18?
Yes this is risk, but I think risk is when you get data from server or other resourses and use this attribute. Could you upvote?
1

You can use ReactHtmlParser for this issue.

It parses string as HTML tag. Slices and turns it to any tag.

import ReactHtmlParser from 'react-html-parser'; 

//Initialize
const string_html = "Exempel <br> <strong>text</strong>, här är <a target='_blank' rel='noreferrer 
noopener' href='https://youtube.com'>länk</a>"

//When render
<> {ReactHtmlParser(string_html)} </>

2 Comments

Hey, thank you! Do you know what is the difference between that and dangerouslySetInnerHTML? Which one is safer to use, when considering security or are the any differences in that sense etc.?
Hi again, dangerouslySetInnerHTML sets the attribute dangerously as its name. This package provides a new line as tag, not edit. It can be dynamic with states as my usage.
1

There is no need to use extra modules...your case is what the Trans component is all about...

While Trans component can parse basic HTML tags like br, strong, ... using an anchor tag needs to pass a react element to the component...

simple tags: https://react.i18next.com/latest/trans-component#usage-with-simple-html-elements-like-less-than-br-greater-than-and-others-v10.4.0

So, your sample when not using content inside Trans children should look something like:

import React, { Suspense } from "react";
import i18n from "i18next";
import { initReactI18next, useTranslation, Trans } from "react-i18next";

const translationSwe = {
about: "Information",
example: "Exempel <br> <strong>text</strong>, här är <MyLink>länk</MyLink>"
}

const translationEng = {
about: "About"
example: "Example <br> <strong>text</strong>, here is <MyLink>link</MyLink>"
}

i18n.use(initReactI18next).init({
resources: {
swe: { translation: translationSwe },
eng: { translation: translationEng },
},
lng: "swe",
fallbackLng: "swe",
interpolation: { escapeValue: false },
});

const App = () => {
const { t } = useTranslation();

return(
<Suspense fallback="Loading..">
<div className="app">
<p><Trans i18nkey="example" components={{ MyLink: <a target='_blank' rel='noreferrer 
noopener' href='https://youtube.com'>link</a> }}/></p>
</div>
</Suspense>
);
};

see https://react.i18next.com/latest/trans-component#alternative-usage-which-lists-the-components-v11.6.0

Comments

0

Use Linkify Package

https://www.npmjs.com/package/react-linkify

Installation:

yarn add react-linkify

or

npm install react-linkify --save

Usage:

import Linkify from 'react-linkify';

React.render(
  <Linkify>Examples are available at tasti.github.io/react-linkify/.</Linkify>,
  document.body
);

Comments

0

You can use html-react-parser lib for this issue. Check doc here

It parses string as HTML tag. Slices and turns it to any tag.

Example

import: import parse from 'html-react-parser';

test string: {"testId": "text test, bold <b>here</b>"}

in code: <h5>⦁ {parse(fastTab)}</h5>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.