i18next / react-i18next

Internationalization for react done right. Using the i18next i18n ecosystem.
https://react.i18next.com
MIT License
9.33k stars 1.03k forks source link

Get the current active language #475

Closed ugogo closed 6 years ago

ugogo commented 6 years ago

Hi!

I'm looking for a way to retrieve the current and active language. Not the detected one (i18n.language).

I could look through i18n.languages and use the fallbackLng as a fallback, but I feel like I'm reinventing the wheel.

Example:

Is there a simple way to get it? Thx!

jamuhl commented 6 years ago

guess as long you do not use the whitelist option you will not get the language which was used on resolve for translation...just the order in i18next.languages -> as for it you have nothing it will be ['it', 'en']

So best would be set

i18next.init({
  whitelist: ['fr', 'en'],
  nonExplicitWhitelist: true,
  load: 'languageOnly',
  fallbackLng: 'en'
});

now you can take i18next.languages[0] that will be either en or fr

ugogo commented 6 years ago

Looks good, it'll do the job Thx!

assainov commented 4 years ago

I needed to detect the current language in my components. Here is what I came up with:

import i18n from 'i18next';

export const getLanguage = () => {
  return i18n.language ||
    (typeof window !== 'undefined' && window.localStorage.i18nextLng) ||
    'en';
};
srvmux commented 4 years ago

now you can take i18next.languages[0] that will be either en or fr

I tried it with i18next.language[0] didn't work, but i18next.language worked for me, thanks for the solution

alekseykarpenko commented 4 years ago

@jamuhl Thx for your previous reply, but it seems I have some special corner case here. E.g., I want Russian browser locale in Ukraine (ru-UA) to fallback into Ukrainian translation (uk):

i18next.init({
  whitelist: ['en', 'uk', ‘ru-UA’],
  nonExplicitWhitelist: true,
  fallbackLng: {
    ‘ru-UA’: [‘uk’]
});

But then I need to check what translation am I using explicitly:

console.log(I18next.language); // -> ‘ru-UA’
console.log(i18next.languages[0]); // -> ‘ru-UA’

Should I walk through init options here to check the real localization used (as @ugogo mentioned) or there is an easier way to do that?

jamuhl commented 4 years ago

As the lng detected is ru-UA it will look there first [0] -> fallbacks for uk should be somewhere in the i18next.languages (guessing last index)

alekseykarpenko commented 4 years ago

@jamuhl Yep, it's there, but I forgot to mention, that I also have a default fallback language (en), so I cant just check for i18next.languages[i18next.languages.length - 1], because in case user has uk locale, that expressions will give en as a result.

So, for those who have such corner cases in future, I've finished up with additional method to get actual locale:

const options = {
  resources: { en, uk }, // previously imported from json files 
  whitelist: ["en", "uk", "ru-UA"],
  nonExplicitWhitelist: false,
  fallbackLng: {
    'ru-UA': ['uk'],
    'default': ['en']
  },

  // ...
}

export const locales = Object.keys(options.resources);
export function getCurrentLocale() {
  return i18n.languages.find((lng => locales.indexOf(lng) !== -1))
}

i18n
  .use(LanguageDetector)
  .use(initReactI18next) // passes i18n down to react-i18next
  .init(options);

export default i18n;
yefrioscar commented 4 years ago

How do you import json files?

alekseykarpenko commented 4 years ago

@yefrioscar Directly, using "resolveJsonModule": true, in my tsconfig.json:

import en from 'translations/translations.en.json'
import uk from 'translations/translations.uk.json'