i18next: Missing languages in the language list

I don’t know if this belongs here or in react-18next, but my language list is wrong after instantiation. I can correctly change the language using changeLanguage(), but logging the language list never shows the whole list.

// Simplified code

import de from './de.json'
import fr from './fr.json'
import en from './en.json'
import es from './es.json'

const resources = { de, fr, en, es } // contains the 'translation' namespace

i18n
  .use(LanguageDetector)
  .init({
    fallbackLng: 'fr',
    resources
  })
// In a React method

this.props.i18n.changeLanguage('en')

console.log(this.props.i18n.language)   // => en
console.log(this.props.i18n.languages)  // => Array ["en", "fr"]

In the above console.log, the only listed languages are the currently selected one and the fallback one. If I change to another language (german for example), it will discard the “en” and change it to “de” : ["de", "fr"]. But isn’t it supposed to display the whole list every time ?

I tried to add these options on init :

{
  whitelist: ['fr', 'en', 'es', 'de'],
  preload: ['fr', 'en', 'es', 'de']
}

But it doesn’t change anything.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 32 (16 by maintainers)

Most upvoted comments

But i guess Object.keys(i18next.services.resourceStore.data); would give you a list of every locale loaded into i18next

the documentation should be updated as this is really confusing 😦

@MariusMeiners regarding what

One would expect languages to include all defined languages in resources. (I just spent half an hour debugging this) IMO if you don’t want to keep such a list in the i18n the languages should be renamed to something more specific.

I also wanted to loop through those display them in simple select.

<select onChange={handleChange}>
      {i18n.languages.map((language, i) => (
        <option key={i} value={language} selected={language === i18n.languages[0]}>
          {languageLabels[language]}
        </option>
      ))}
 </select>

and I expected this to work.

@spike-barry-northern The point is - i18next has no idea (nor a need) for languages you provide - it only knows what language was detected or set and from there builds a list of languages to load and to look translations up from.

Thanks, I do understand that from the docs now, but it was a slow process of realisation from a reasonable assumption. I totally accept that it works the way it does, and the way it works is correct. I saw it as my failing to initially understand, but when I came here, realised it wasn’t just me, and wondered if something in the docs could be clearer, that’s all. Maybe something like: “you might think this is a list of configured languages, but it isn’t …”

By the way, i18next is AMAZING! I love it.

ok i see…guess you can either pull those like mentioned Object.keys(i18next.services.resourceStore.data); or provide them yourself…as you know which languages you have.

Using our Translation management https://locize.com you would be able to get the languages from the used backend or API: https://docs.locize.com/integration/api#fetch-the-available-languages

@PeterBenc your resources should not really contain all languages you provide - at least not in web - for mobile that might be ok…

so you should keep track of what languages you support yourself or use the supportedLanguages for that…

reading the docs it should be clear what and why i18next.languages exist and is not the same as i18next.language https://www.i18next.com/overview/api#languages

So you mean that when I use changeLanguage(), it just pushes the user’s choice to the top of the array, and i18n selects the first available language in this array ? If so, yes documentation is very unclear ! Thanks for clarification though.

Do I have a way to know the entire list of available languages so ? Currently I loop through the keys of i18n.options.resources, but I don’t know if that’s a good idea.

I would use it to generate a dynamic language selector on a menu, but alright. Thanks for your fast replies ! 👍

Do I have a way to know the entire list of available languages so ? Currently I loop through the keys of i18n.options.resources, but I don’t know if that’s a good idea.

Know for what? what you like to do with the list of languages?

@rickstaa just a correction: Additionally, users can preload languages on construction by specifying them in the supportedLngs initialization option. <<-- it’s preload to preload additional languages https://www.i18next.com/overview/configuration-options#languages-namespaces-resources

@rickstaa with a remote backend plugin you need something like you’ve described with your github action. Alternatively if you’re using locize, you can use: https://github.com/locize/i18next-locize-backend#backendgetoptions

It’s been a while since I commented on this issue, but I still think that a native way to get the entire list of available languages could be useful.

or provide them yourself…as you know which languages you have.

Most of the time I actually don’t know what languages I have, so I prefer to have a dynamic way to generate my languages list. Imagine that I add a new supported language to either locize or phrase (or whatever backend you use). If I download then inject all of them during the build phase, based on an api call (which I do), I don’t know which ones I have available to me.

Of course crafting the language menu on my own is “fine”, I don’t add new languages to my application that often. But you know how it goes, we’re just lazy developers.

It could be as simple as a getter maybe? I haven’t checked the source code to see if there’s a class for it though.

get languageList () {
    return Object.keys(this.services.resourceStore.data);
}

A solution like that built directly in i18next would only work if all resources/languages are preloaded, so working with a lazy loading backend or similar would just give a wrong language list…

@rohitjpsingh I suspect you’ve loaded stale language data because of the caching, the https://docs.locize.com/integration/api#fetch-the-available-languages request is cached 1h by default… In case you need more help, send an email at: support@locize.com