React + i18next: Why aren't my nested keys working?
Asked Answered
D

2

31

I am using ReactJS for a small website. I decided to use i18next for the internationalization and it works - unless I use a nested reference for the translation key.

In the following example the intro1 and intro2 key are displayed, but welcome.headtitle is not found (error "missingKey" in the console).

App.js:

...
 <p><Trans i18nKey='intro1'/></p>
 <p><Trans i18nKey='intro2'/></p>
 <p><Trans i18nKey='welcome.headtitle'/></p>
...

translation.json:

{
  "welcome": {
    "headtitle": ...
    ...
  },
  "intro1": ...,
  "intro2": ...,
}

I know that i18next allows for nested JSON translation objects. What am I doing wrong? I have checked the documentation and examples and didn't notice any error.

Diamond answered 28/8, 2019 at 11:43 Comment(1)
Could you post your i18n initialization code?Inceptive
M
66

while the answer to use "welcome.name" etc is a valid usage, for my use case, I actually needed to use structured keys so that I can better structure my translations.

What made the nested values work for me was removing the keySeparator: false from the i18n.init function.

Code would be:


i18n.use(initReactI18next).init({
  resources: {
    en: {translation: EN},
    fr: {translation: FR},
  },
  lng: 'en',
  fallbackLng: 'en',
  // keySeparator: false, // this was the line that I've had to remove to make it work
  // keySeparator: '.', // if you want to re-enable it (not "true", but actual separator value)
  interpolation: {
    escapeValue: false,
  },
});

and my JSON looks like:

{
  "nested": {
    "value": "Trying a nested value"
  }
}

my HTML (div in my react component):

<div>{t("nested.value")}</div>

If you want to re-enable nested keys, don't use keySeparator: true. You need to specify key separator symbol like this: keySeparator: '.' (thanks @glinda93 for specifying this :) ).

Millais answered 17/1, 2020 at 12:18 Comment(3)
FYI, if you want to reenable nested keys, don't use keySeparator: true. You need to specify key separator symbol like this: keySeparator: '.'Longmire
thanks, this fixed it and in my opinion i think this should be a stand-alone answer, not a comment so that the users can see it betterTseng
Many thanks @glinda93. Have added the correction as suggested :) .Millais
O
1

To add more details to the answer, the key itself might have periods, as in

{
  "root": {
    "nested.key": "This is a nested key with a period"
  }
}

In this case, it can be useful to have a different separator just for the specific usecase, so you can add the options object to the t function as a second argument, specifying a different key separator, such as:

t('root##nested.key', {keySeparator: '##'})

This is especially useful in cases where you have an already working big project with dots used as a separator all over, and some UI update requires this kind of key with dots inside them. If the keySeparator is set in the init method, you would need to change the first parameter all over the project. By overwriting the keySeparator in a specific call to the t method, you can keep the rest of the project unchanged.

Olimpia answered 30/5 at 12:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.