Search code examples
functionreact-nativetranslatei18next

Change language of whole react-native app


My app in react-native has 2 languages: english and french. I've done a i18n.js file and 2 "translation.js" files for english and french. It's working great (i've tried it setting french on my phone, english on the emulator).

Now, I want to make a button in the app's settings to change the language of the entire app for the user but I don't know what function call and how to create this.

Can you help me ? Thanks a lot for your time and help.

my i18n.js file;

import i18n from "i18next";
import detector from "i18next-browser-languagedetector";
import { reactI18nextModule } from "react-i18next";
import { NativeModules, Platform } from "react-native";

import en from "../public/locales/en/translation.js";
import fr from "../public/locales/fr/translation.js";

// the translations
const resources = {
  en: {
    translation: en
  },
  fr: {
    translation: fr
  }
};
const locale =
  Platform.OS === "ios"
    ? NativeModules.SettingsManager.settings.AppleLocale
    : NativeModules.I18nManager.localeIdentifier;

i18n.locale = locale;

i18n
  .use(detector)
  .use(reactI18nextModule) // passes i18n down to react-i18next
  .init({
    resources,
    lng: locale.substring(0, 2),
    fallbackLng: "en", // use en if detected lng is not available

    keySeparator: ".", // we do not use keys in form messages.welcome

    interpolation: {
      escapeValue: false // react already safes from xss
    }
  });

export default i18n;

And I'd like to change the language from my Settings.js file :

<SettingsList.Item
              // icon={<Image style={styles.image} source={require('../../assets/images/icon_vol-mute.png')}/>}
              title={i18n.t("settings.action.languages")}
              hasNavArrow={false}
              switchState={this.state.activeSwitch === 3}
              switchOnValueChange={this.switchThree}
              hasSwitch={true}
              onPress={() => Alert.alert("French / English")}
            />

Solution

  • If you are using i18next

    you can i18next.changeLanguage use to change your language

    export const changeLanguage = (languageKey) => {
    i18next.changeLanguage(lng, callback) // -> returns a Promise
    }
    
    import { changeLanguage } from 'services/translation';
    
    <Button onPress={() => {changeLanguage(languageKey)}} />
    

    But i recommended change to use react-native-localization instead of i18next by simply in implementation and native performance

    How to use react-native-localization?

    Installation

    yarn add react-native-localization --save
    
    #react-native >= 0.60
    cd ios && pod install && cd ..
    
    #react-native < 0.60
    react-native link react-native-localization
    

    Declare your translations

    import LocalizedStrings from 'react-native-localization';
    import english from './en.js'
    import french from './fr.js'
    import korean from './kr.js'
    
    const strings = new LocalizedStrings({
     en: english,
     fr: french,
     kr: korean,
    });
    

    with en.js, fr.js, kr.js are the files contain your translations in key value format.

    eg: content of fr.js

    export default {
    ok: 'D'accord',
    no: 'non'
    }
    

    You can also use json file type for declaration.

    usage

    import strings from 'services/translation';
    
    <Text style={styles.title}>
      {strings.ok}
    </Text>
    

    Change languages

    write a function to change your app language and use it in every where you want.

    const strings = new LocalizedStrings({
     en: english,
     fr: french,
     kr: korean,
    });
    
    
    export const changeLanguage = (languageKey) => {
    strings.setLanguage(languageKey)
    }
    
    import { changeLanguage } from 'services/translation'
    
    
    <Button onPress={() => {changeLanguage(languageKey)}} />
    

    Notes: Do not declare key same at default methods like setLanguage

    See more about react-native-localization here