繁体   English   中英

react-i18next:如何同步浏览器和Express LanguageDetector?

[英]react-i18next: How to sync Browser and Express LanguageDetector?

在服务器的路由中,我这样做是这样的(注意: i18next-express-middleware已经在管道中,并且Server Side Rendering运行良好):

export default function (req, res) {
  const lng = req.language.toUpperCase()

  console.log(lng) // Always display [EN]

  MyModel
    .findOne(query, { fieldEN: 1, fieldFR: 1 })
    .exec()
    .then(res => reply(res[`field${lng}`]))
    .catch(err => handle(err))
}

因此,我尝试根据用户选择的语言返回正确的字段版本。

但是,无论在浏览器端选择哪种语言,在服务器端始终将其设置为默认值EN。

有没有办法让服务器端LanguageDetector知道浏览器端的当前语言?

这是我的客户i18n init

import i18n from 'i18next'
import Backend from 'i18next-xhr-backend'
import LanguageDetector from 'i18next-browser-languagedetector'

i18n
  .use(Backend)
  .use(LanguageDetector)
  .init({
    whitelist: ['en', 'fr'],
    fallbackLng: 'en',
    preload: ['en', 'fr'],

    // debug: true,

    interpolation: {
      escapeValue: false
    },

    ns: ['home', 'channel', 'common'],
    defaultNS: 'home',

    backend: {
      loadPath: '/locales/{{lng}}/{{ns}}.json'
    },

    react: {
      wait: true,
      bindI18n: 'languageChanged loaded',
      bindStore: 'added removed',
      nsMode: 'default'
    }
  })

export default i18n

这是我的服务器i18n init

import i18n from 'i18next'
import Backend from 'i18next-node-fs-backend'
import { LanguageDetector } from 'i18next-express-middleware'

i18n
  .use(Backend)
  .use(LanguageDetector)
  .init({
    whitelist: ['en', 'fr'],
    fallbackLng: 'en',
    preload: ['en', 'fr'],

    // debug: true,

    interpolation: {
      escapeValue: false
    },

    ns: ['home', 'channel', 'common'],
    defaultNS: 'home',

    backend: {
      loadPath: `${__dirname}/public/locales/{{lng}}/{{ns}}.json`,
      jsonIndent: 2
    }
  })

export default i18n

github上的猜测问题https://github.com/i18next/react-i18next/issues/471给出了答案...

而且没有stackoverflow ...我不会在这里再次写完整的答复;)

将代码粘贴到这里,它将/应该工作...但是阅读上面的问题-缺少一个片段-创建一个新实例(除了进入req的那个实例)并在那里设置语言->如果依赖于检测并导致异步没有正确设置initialLanguage ...

实际上,问题不是我的i18n init配置。

在执行SSR时,必须记住,我们有两个不同的i18next实例,一个在服务器上运行,另一个在浏览器中运行。

在您在服务器上创建的实例上,将根据您的配置检测到当前语言。 然后,您将在服务器上呈现以下内容:

<I18nextProvider i18n={i18n_}>
    <StaticRouter location={req.url} context={{}}>
        <Route component={App} />
    </StaticRouter>
</I18nextProvider>

但是,当您的浏览器应用启动时,它将使用从其自己的配置中检测为当前语言的任何内容。

因此,第一件事就是使用来自服务器的i18n信息初始化浏览器应用。 因此,在构建标记服务器端时,只需在window对象上创建两个属性来保存initialStoreinitialLanguage (注意:我使用hbs ):

window.__initialI18nStore__ = {{json initialI18nStore}}
window.__initialLanguage__ = {{json initialLanguage}}

然后在浏览器应用程序上,您将使用以下内容进行渲染:

<I18nextProvider
    i18n={i18n}
    initialI18nStore={window.__initialI18nStore__}
    initialLanguage={window.__initialLanguage__}
  >
      <BrowserRouter>
          <Route component={App} />
      </BrowserRouter>
</I18nextProvider>

因此,浏览器应用程序将使用相同的语言并从服务器存储。

但是您还没有完成。 使用相同的语言初始化浏览器应用程序不会链接i18next的两个实例,如果您在浏览器上更改语言,然后按刷新,您仍将使用来自服务器的先前语言,因为i18next的服务器实例是不知道您所做的更改。

解决所有这些问题的方法是LanguageDetectorcaches设置。 您必须在配置,浏览器和服务器上都指定它:

detection: {
  caches: [..., 'cookie', ...]
}

例如,当您使用cookie时,每次浏览器更改语言时,cookie都会更新,然后在服务器端,语言检测器的行为将被更改,它将首先尝试从中获取当前语言。 cookie,并将其设置为req.i18n.language 因此,这两个实例现在将通过该Cookie进行同步。

可能是您应该阅读react-i18next github react-i18next库上的示例razzle-ssr ,并检查以下链接以了解有关LanguageDetector选项的更多信息: 对于浏览器节点

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM