react-i18next: Error occurs on render when using tOptions.interpolation
🐛 Bug Report
With the merge of my PR https://github.com/i18next/react-i18next/pull/1204, when I try to pass interpolation to tOptions
, an error occurs. When I remove the tOptions
prop that I passed in, then it works, which is very weird 🤔.
In the console
React on the first few lines says:
The above error occurred in the <br> component:
in br (at dashboard-greeting/index.tsx:40)
in Trans (at dashboard-greeting/index.tsx:34)
In the very last line of console
React says React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.
To Reproduce
To reproduce this you would have to use Trans
like this:
<Trans
i18nKey="home:UserGreetingHeadline"
defaults="Hallo {{ firstName }},<br/>
willkommen auf <bold>meine</bold>tonies, hier kannst du ganz zentral
Deine Toniesammlung und Tonieboxen verwalten."
values={{ firstName: 'Tiger<no>' }}
components={{ br: <br />, bold: <strong /> }}
tOptions={{ interpolation: { escapeValue: true } }}
/>
As for the i18nKey
, you do not have to specifically put it into a home.json file 👍.
Expected behavior
I do expect this to at least be able to render, with or without tOptions
prop. I still find it very strange that it is working when I do not use the tOptions
prop.
PS. I am happy to work on whatever has to be fixed in case this happens because of either my last PR or if anything else has to be changed 💕.
Pictures
Picture of the error:
Picture when not using tOptions
prop, then it works apparently 🤔 :
Here the message is also broken because of the HTML tags in firstName
😢.
Your Environment
- runtime version: i.e. node v14.15.0
- i18next version: i.e. 11.7.4
- os: Linux, Ubuntu
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 42 (37 by maintainers)
just set
https://codesandbox.io/s/react-i18next-forked-0opfv and results are the same
and yes…you can just use the other tags (strong, br, …) as is in the translations…
Yes, the HTML.parse call is the problem.
Analyze html-parse-stringify2 and propose a fix there or find an alternative.
That looks good to me, too: https://codesandbox.io/s/react-i18next-forked-1hfow?file=/src/app.js
I think we’ll set this in our global config then, to avoid the escaping issue globally.
I wonder if this should be mentioned in the documentation. I’m sure @tigerabrodi would be happy to do a PR for that 😃
@tigerabrodi would guess so…
Yes, HTML.parse takes the tag and converts it to something valid -> <no3> -> assumes non self-closing tag…
But one can also see: https://codesandbox.io/s/react-i18next-forked-eig23 works for
(which is in the
transKeepBasicHtmlNodesFor
list)Main difference:
t
always gives you a stringTrans
tries its best to create a valid react component tree from the translation and node children it getswell if it works with
<no>
you would have to define what you accept…allowing HTML inside user input is always a bit risky as it opens the door for injecting malicious scripts…@adrai Hmm, seems like html-parse-stringify2 was last updated three years ago https://github.com/rayd/html-parse-stringify2
Actually this is still broken 😕 When adding an unclosed tag, it again breaks the rendering badly: https://codesandbox.io/s/react-i18next-forked-1hfow?file=/src/app.js:381-437 Despite using
transSupportBasicHtmlNodes: false
To me it looks like a bug that
<Trans>
doesn’t escapevalues
liket()
does.Since setting
escapeValue: true
breaks it in a different way, that doesn’t seem like a good “not a bug, its a feature” explanation.If it is a bug, could you reopen the issue? Or should we (@tigerabrodi or me) file a new one? We could dig into the implementation to see if we can come up with a solution.
The
br
in components props does not work as https://react.i18next.com/latest/trans-component#alternative-usage-v-11-6-0 (see the warning: Existing self-closing HTML tag names are reserved keys).The
br
in the translation will be converted to valid react element thanks to: https://react.i18next.com/latest/trans-component#using-for-less-than-br-greater-than-and-other-simple-html-elements-in-translations-v-10-4-0Not had the time to create a reproducible sample but my guess is that setting
{ escapeValue: true }
conflicts with interpolating react elements into the result.to get
Tigern<no>
working adding it to the https://react.i18next.com/latest/trans-component#using-for-less-than-br-greater-than-and-other-simple-html-elements-in-translations-v-10-4-0 might already work - but not tested myself.->
i18next.options.react: { ..., transKeepBasicHtmlNodesFor: ['br', 'strong', 'i', 'p', 'no'] }
This is what @jamuhl tried to explain here: https://github.com/i18next/react-i18next/pull/1204#issuecomment-737062765
Does it work if you remove the “< br >” from the components prop? like:
components={{ bold: <strong /> }}