Can not get i18n value after changeLanguage

Viewed 44

I have try to code an endpoint in express and here is my file structure:

.
├── API/
│   └── login.js
└── i18n/
    └── index.js

login.js (I tried to use i18n.t() and i18n.getResource()

import React, { Component, useEffect, useState } from "react"
import { Redirect, useHistory } from "react-router-dom"
import MetaTags from "react-meta-tags"
import { useTranslation } from 'react-i18next'

export default function Login(props) {
  const dispatch = useDispatch()
  const history = useHistory()
  const { t, i18n } = useTranslation("ActivateActivate")

  const changeLanguageHandler = (lang) => { 
    i18n.changeLanguage(lang) 
    console.log(i18n.language, i18n.t("Login Now"), "i18n.t")
    console.log(i18n.language, i18n.getResource(i18n.language, "ActivateActivate", "Login Now"), "i18n.getResource")
  }
  useEffect(() => {
    changeLanguageHandler("zh-hk") 

    changeLanguageHandler("en")

    changeLanguageHandler("zh-hk") 
  }, [])

  return (
    <div>
      ...
    </div>
  )
}

i18n/index.js

import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import { initReactI18next } from "react-i18next";
import Backend from 'i18next-http-backend';

let resources = {
  "en": {
    "ActivateActivate": {
      "Login Now": "Login Now現在登入"
    },
  },
  "zh-hk": {
    "ActivateActivate": {
      "Login Now": "現在登入"
    },
  },
}

i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    resources,
    preload: ['en', 'zh-hk', 'zh-cn'],
    fallbackLng: "en",
    debug: true,

    // have a common namespace used around the full app
    ns: ["ActivateActivate"],
    // defaultNS: "ActivateActivate",
    
    keySeparator: false, // we use content as keys
    interpolation: {
      escapeValue: false
    }
  });

export default i18n;

Here is the result:

i18next: languageChanged zh-hk
i18next.js:31 i18next::translator: missingKey zh-hk translation Login Now Login Now
Login.js:125 zh-hk Login Now i18n.t
Login.js:126 zh-hk 現在登入 i18n.getResource
i18next.js:31 i18next: languageChanged en
i18next.js:31 i18next::translator: missingKey en translation Login Now Login Now
Login.js:125 en Login Now i18n.t
Login.js:126 en Login Now現在登入 i18n.getResource
i18next.js:31 i18next: languageChanged zh-hk
i18next.js:31 i18next::translator: missingKey zh-hk translation Login Now Login Now
Login.js:125 zh-hk Login Now i18n.t
Login.js:126 zh-hk 現在登入 i18n.getResource

For the result, i18n.getResource() selecting correct language, but i18n.t() mapping wrong value, my question is:

  1. Why showing "translator: missingKey en translation" in error log?
  2. What is the reason that i18n.t() mapping wrong value?

How can I fix? Thanks all!

======================================

[Update] I found that i18n.t() is not work in my codes reason:

  1. i18n.t() using default namespace "translator" which is not my selecting namespace
  2. i18n.t() can not switch language after using i18n.changeLanguage()

Is that helpful for solve problem?

1 Answers

You missed the namespace level in the resources:

let resources = {
  "en": {
   "translation": {
    "ActivateActivate": {
      "Login Now": "Login Now現在登入"
    }
   }
  },
  "zh-hk": {
   "translation": {
    "ActivateActivate": {
      "Login Now": "現在登入"
    }
   }
  }
}

and you also need to use the correct key path in the t call:

i18n.t("ActivateActivate.Login Now")
Related