【问题标题】:HTML tags in i18next translation files in ReactReact 中 i18next 翻译文件中的 HTML 标签
【发布时间】:2017-02-11 16:18:10
【问题描述】:

我在一个项目中使用i18next,无法在翻译文件中包含html标签并正确呈现它们。

我的.json翻译文件示例:

"en": {
  "product": {
    "header": "Welcome, <strong>User!</strong>"
  }
}

有一个excellent answer to this question,但与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);

在我的组件中:

import t from 'i18n';

t('product.header')

我想要的HTML:

Welcome, <strong>User!</strong>

我得到的 HTML:

Welcome, &lt;strong&gt;User!&lt;/strong&gt

谢谢

【问题讨论】:

  • 您解决了这个问题吗?
  • @Petr Gaxarov - 如果你找到了,请分享解决方案。

标签: javascript html reactjs internationalization i18next


【解决方案1】:

不要在翻译中加入 HTML 标签。无论如何,这是一个坏主意。 关注点分离 伙计们都会对此发牢骚。

如果 react-i18next https://react.i18next.com/latest/trans-component

,则使用 &lt;Trans&gt; 组件

这样做:

// Component.js

<Trans>Welcome, <strong>User!</strong>, here's your <strong>broom</strong></Trans>

以及对应的翻译文件:

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

这些数字 会让你觉得是随机的,但请耐心等待:

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
]

旁注(可以认为是一种 hack,但可以节省大量时间): react.i18next.com 的人在他们的文档中没有这个,但您可以使用基本语言作为 key(在这种情况下为英语)。它可以节省您的时间,而不是像他们在他们的文档中显示的那样重复翻译,我引用:

// 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>
  );
}
// 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>.",

无论如何,“荣誉!”加入 i18next 团队!你们太棒了,伙计们!

这里 - go nuts!

【讨论】:

    【解决方案2】:

    不是 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 将其转换为格式化内容。

    【讨论】:

    【解决方案3】:

    由于react-i18next@11.6.0,您可以在翻译字符串中使用标签,并将其替换为Trans 组件中的component 属性或useTranslation 钩子中的t 属性:

    https://react.i18next.com/latest/trans-component#alternative-usage-which-lists-the-components-v-11-6-0

    使用示例:

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

    【讨论】:

      猜你喜欢
      • 2013-04-08
      • 1970-01-01
      • 1970-01-01
      • 2023-02-20
      • 1970-01-01
      • 1970-01-01
      • 2022-06-12
      • 2019-07-16
      相关资源
      最近更新 更多