Pet*_*rov 12 html javascript internationalization i18next reactjs
我在一个项目中使用i18next并且无法绕过在翻译文件中包含 html 标签并正确呈现它们。
我的.json翻译文件的一个例子:
"en": {
"product": {
"header": "Welcome, <strong>User!</strong>"
}
}
Run Code Online (Sandbox Code Playgroud)
这个问题有一个很好的答案,但与 JQuery 相关。我没有使用 JQuery,我的项目是 React,这是我的设置:
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);
Run Code Online (Sandbox Code Playgroud)
在组件中,我有:
import t from 'i18n';
t('product.header')
Run Code Online (Sandbox Code Playgroud)
我想要的 HTML:
Welcome, <strong>User!</strong>
Run Code Online (Sandbox Code Playgroud)
Html 我得到:
Welcome, <strong>User!</strong>
Run Code Online (Sandbox Code Playgroud)
谢谢
Jan*_*roň 15
由于react-i18next@11.6.0,您可以在翻译字符串中使用标签,并将其替换为组件components中的 propTrans或钩子中t的属性useTranslation:
https://react.i18next.com/latest/trans-component#using-with-react-components
使用示例:
<Trans
i18nKey="myKey" // optional -> fallbacks to defaults if not provided
defaults="hello <italic>beautiful</italic> <bold>{{what}}</bold>" // optional defaultValue
values={{ what: 'world'}}
components={{ italic: <i />, bold: <strong /> }}
/>
Run Code Online (Sandbox Code Playgroud)
不要将 HTML 标签放在翻译中。总之这是个坏主意。关注点分离的人都会对此发牢骚。
使用<Trans>组件如果react-i18next https://react.i18next.com/latest/trans-component
这样做:
// Component.js
<Trans>Welcome, <strong>User!</strong>, here's your <strong>broom</strong></Trans>
Run Code Online (Sandbox Code Playgroud)
以及对应的翻译文件:
// 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>",
}
Run Code Online (Sandbox Code Playgroud)
这些数字<1>和<3>会让你觉得随机但等待它:
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
]
Run Code Online (Sandbox Code Playgroud)
旁注(可以被认为是一种 hack,但可以节省大量时间): react.i18next.com 上的人,在他们的文档中没有这个,但是你可以使用基本语言作为关键(在这种情况下是英语)。它可以节省您的时间,而不是像他们在他们的文档中显示的那样重复翻译,我引用:
// 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>
);
}
Run Code Online (Sandbox Code Playgroud)
// 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>.",
Run Code Online (Sandbox Code Playgroud)
无论如何“荣誉!” i18next 团队!你们太棒了,伙计们!
在这里 -疯了!
不是 react-i18next 的问题——你只是不能将 html 添加到 react 元素中。react 将保护您免受 xss 漏洞的影响并逃脱内容:
更多细节和可能的解决方案:https : //facebook.github.io/react/tips/dangerously-set-inner-html.html
但请注意,如果您将用户内容放置在那里,则您的网站会受到 xss 攻击。
更安全地阅读 react-i18next 自述文件:https : //github.com/i18next/react-i18next#interpolate-component
这让你拆分内容
所以“最佳”解决方案——至少我们所做的——是在翻译中使用降价并使用例如:https : //github.com/acdlite/react-remarkable将其转换为格式化内容。