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)
-