Only first language in list of browser languages is considered?
dgmstuart opened this issue Β· comments
π Bug Report
It seems like only the first item in the user's list of browser languages is used, even if that language is not supported by the application, but there are items later in that list which are supported?
Scenario:
- The app supports
en
,sv
,fr
- The app has a fallback of
en
- The user's browser languages (Chrome) are
['es', 'sv', 'en']
(checked both in Chrome settings and in the console withnavigator.languages
)
Expected behaviour:
-
sv
should be used, since:- it's a language in the user's preferred languages in the browser
- it's a language which the app supports
- it's the earliest detected language in the list which is supported by the app
-
sv
should be stored in localstorage -
the
i18n
object should include:{
'language': 'sv',
'languages': ['sv', 'en'],
'resolvedLanguage':'sv'
}
Actual behaviour:
-
the fallback
en
is used for translations -
es
is stored in localstorage -
the
i18n
object includes:{
'language': 'es',
'languages': ['es', 'en'],
'resolvedLanguage':'en'
}
Code
Everything I've seen looking at the source code and other issues seems to suggest that the intention is to fetch all the languages from the browser: (
i18next-browser-languageDetector/src/browserLookups/navigator.js
Lines 8 to 12 in 80754d8
...and to return all of them so that i18next can pick the best match, though for older versions of i18next it falls back to just picking the first one:
i18next-browser-languageDetector/src/index.js
Lines 78 to 79 in 80754d8
So I'm wondering if there's an issue with that check and it's using the fallback behaviour of just picking the first language in the list?
Or is there some issue with my config? Am I supposed to explicitly be telling LanguageDetector
that I'm using i18next
? Seems unlikely:
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import en from "./locales/en.json";
import fr from "./locales/fr.json";
import sv from "./locales/sv.json";
i18n.use(LanguageDetector).use(initReactI18next).init({
resources: { en, fr, sv },
fallbackLng: "en",
});
App
The app I'm trying this is open source: https://github.com/dgmstuart/bingo-frontend
I'm happy to make a minimal reproduction app, but I wanted to check first if this was just my misunderstanding or misconfiguration.
My Environment:
- runtime version: browser: chrome
- i18next version: 23.11.2
- os: Mac
getBestMatchFromCodes will pick the first detected lng code if you do not specify the supportedLngs
option:
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import en from "./locales/en.json";
import fr from "./locales/fr.json";
import sv from "./locales/sv.json";
i18n.use(LanguageDetector).use(initReactI18next).init({
resources: { en, fr, sv },
supportedLngs: ['en', 'sv', 'fr'],
fallbackLng: "en",
});
Oh neat! Thank you π
I found it in the list of configuration options now, but I didn't see it in any of the example code - I'm happy to make a documentation PR if you think that's helpful?
Is it used for anything else, or is it specific to this plugin? It doesn't seem to need to be defined for translations to work?
it's not really specific to this languageDetector plugin...
feel free to provide a pr
Added a PR here: #284
I understand that supportedLngs
isn't specific to this plugin, but am I correct in understanding that it is only used in relation to language detection?
I tried to find a place on https://www.i18next.com/ to add some documentation, but the docs there all seem to delegate any documentation about language detection to the individual plugins, which makes sense, but makes it hard to add any examples.