links: [[React Native MOC]] created_at: 2021-10-24 --- # How to setup Localization support in React Native In order to support multiple languages in your app you need to setup i18n and RTL. ## Setup i18n Install necessary dependencies ```sh yarn add i18n-js react-native-localize ``` Let's add some translations Create couple of files that represents the language filename: en.json (English) ```json { "registerScreen": { "firstName": "First Name", "lastName": "Last Name", "username": "Username", "email": "Email", "password": "Password" } } ``` filename: ar.json (Arabic) ```json { "registerScreen": { "firstName": "الاسم الأول", "lastName": "اسم العائلة", "username": "اسم المستخدم", "email": "البريد الإلكتروني", "password": "شعار" } } ``` Since we have translations in place let's configure localization filename: localization.js ```js const translationGetters = { // lazy requires ar: () => require("./ar.json"), en: () => require("./en.json") } const rtlGetters = { en: false, ar: true, }; // Memoized version of translate export const translate = memoize( (key, config) => i18n.t(key, config), (key, config) => (config ? key + JSON.stringify(config) : key), ); export const setI18nConfig = updatedLanguage => { // clear any cache before language is updated translate.cache.clear(); // forceRTL should be used only on dev mode for testing purposes without changing language // I18nManager.forceRTL(rtlGetters[updatedLanguage]); // if `updatedLanguage` is not passed then use device language if (!updatedLanguage) { const fallback = {languageTag: 'en', isRTL: false}; const {languageTag, isRTL} = RNLocalize.findBestAvailableLanguage(Object.keys(translationGetters)) || fallback; // isRTL is not available on i18n object. we are adding in order to use it in components i18n.isRTL = isRTL; // we are only adding required translation, instead of adding all translations i18n.translations = { [languageTag]: translationGetters[languageTag](), }; // setting locale i18n.locale = languageTag; } // use language from async storage. else { i18n.isRTL = rtlGetters[updatedLanguage]; i18n.translations = { [updatedLanguage]: translationGetters[updatedLanguage](), }; i18n.locale = updatedLanguage; } }; ``` Since we have the base setup. All we have to do now is provide code to initialize language or change language on your `app.js` or `app.ts` where you start your services or setting up stores. let's add this ```js import {setI18nConfig} from './localization' const App = () => { useEffect(() => { // Load translations setI18nConfig() // setRootStore }, []) } ``` If you have a screen with list of languages. you can do something like this on language-selector-screen.jsx ```js const LanguageSelector = () => { return ( <Screen> <Text style={styles.text}> {`Selected Language: ${i18n.currentLocale()}` </Text> <Button title={'English'} onPress={() => setI18nConfig('en')} /> <Button title={'Arabic'} onPress={() => setI18nConfig('ar')} /> </Screen> ) } ``` I will leave upto you to trigger a re-render on whole app so translations gets updated. You can use some state management like mobx or redux, or you can even use context. Here are some helper components for localization ```js const Row = ({children, style, ...props}) => { // use stylesheet for perf improvements. const baseStyle = {flexDirection: i18n.isRTL ? 'row-reverse' : 'row'}; return ( <View style={[baseStyle, style]} {...props}> {children} </View> ); }; const Column = ({children, style, ...props}) => { const baseStyle = { flexDirection: i18n.isRTL ? 'column-reverse' : 'column', }; return ( <View style={[baseStyle, style]} {...props}> {children} </View> ); }; const Text = ({children, style, ...props}) => { const baseStyle = {writingDirection: i18n.isRTL ? 'rtl' : 'ltr'}; return ( <BaseText style={[baseStyle, style]} {...props}> {children} </BaseText> ); }; ``` ### iOS Setup For iOS you have to add localization files to the app. Open XCode and select your project. Under the info tab you can find localizations. Add the desired languages. Now from the file menu select Add File -> localization (strings file) Create a file and now select the right side bar. You can see localization now select required translations. That's it Voila 🎉 Now your app supports localization without app restarts or hacks --- tags: #rtl #i18n #internationalization #react-native, #localization sources: sources: - [Localize iOS App](https://www.youtube.com/watch?v=WSI_LS3Yq8I) - [React Native Blog about i18n](https://reactnative.dev/blog/2016/08/19/right-to-left-support-for-react-native-apps) - [RTL support for react native](https://medium.com/@p.nasirimehr/adding-rtl-support-to-an-existing-react-native-app-in-2020-3264d035cb49) - [React Native Localize](https://github.com/zoontek/react-native-localize) - [Localizations iOS](https://github.com/facebook/react-native/issues/13406) - [Change direction of app](https://stackoverflow.com/questions/53554153/react-native-support-rtl-and-ltr-without-changing-device-language?rq=1) -