How to get current locale with i18next / react-i18next?

Viewed 6361

I'm new to react-native and I'm trying to get current locale from the device of the user. For now, I have 2 versions of my app : french and english. It works fine when I change the fallback language I do have the two versions of the app. But I can't manage to change the language directly from the device.

We can change manually, but if we have set french language on device then we can't get french language directly.

enter image description here

import i18next from 'i18next';
import {initReactI18next} from 'react-i18next';

const languageDetector = {
  type: 'languageDetector',
  async: true,
  detect: cb => cb('en'),
  init: () => {},
  cacheUserLanguage: () => {},
};

i18next
  .use(languageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: 'en',
    debug: true,
    resources: {
      en: {
        translation: {
          hello: 'Hello world',
          change: 'Change language',
        },
      },
      sv: {
        translation: {
          hello: 'Hallo!',
          change: 'Goedemorgen',
        },
      },
    },
  });

export default i18next;

App.js

import React from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import { useTranslation } from 'react-i18next';
import './src/Traslations'


export default function App() {
  const { t, i18n } = useTranslation();
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text style={{ fontSize: 20, marginBottom: 20 }}>{t('hello')}</Text>
      <Text style={{ fontSize: 20, marginBottom: 20 }}>{t('change')}</Text>

      <TouchableOpacity style={{backgroundColor: 'pink'}} onPress={() => i18n.changeLanguage(i18n.language === 'nl' ? 'en' : 'nl')}>
        <Text>{t('change')}</Text>
      </TouchableOpacity>
    </View>
  );
  }
2 Answers

Your languageDetector uses en as a fallback lang...

Make Sure that the language-prefix you choose in your device is sv <<-- the key you're having in your i18n setup...

const languageDetector = {
  type: 'languageDetector',
  async: true,
  detect: cb => cb('en'), // <<---- here
  init: () => {},
  cacheUserLanguage: () => {},
};

Instead

You'd want to pass current-device-lang

import { Platform, NativeModules, Dimensions } from 'react-native';
const getDeviceLang = () => {
  const appLanguage =
    Platform.OS === 'ios'
      ? NativeModules.SettingsManager.settings.AppleLocale ||
        NativeModules.SettingsManager.settings.AppleLanguages[0]
      : NativeModules.I18nManager.localeIdentifier;

  return appLanguage.search(/-|_/g) !== -1
    ? appLanguage.slice(0, 2)
    : appLanguage;
};

detect: async callback => {
  const deviceLang = getDeviceLang();
  callback(appLanguage);
},

More details could be found here with a working sample...

Related