簡體   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