Creating a Multi-Language App in React Native
Tags: reactnative, reactnativelocalize, i18n, multilangugae
Published: 2019-07-08 17:12:46

---
title: Creating a Multi-Language App in React Native
published: true
description: Adding multi-language support to React Native apps using react-native-localize and i18n
tags: React Native, react-native-localize, i18n, Multi langugae,
cover_image: https://thepracticaldev.s3.amazonaws.com/i/s7xaticsakwh8ozu6akt.jpg
---

Language has always been an essential part of any business. As the business grows it becomes important for the business to expand in different countries and regions. To achieve success in these local regions it is important to provide localization.

When it comes to the mobile app, the conditions are no different. As the app users expand to different countries, it becomes important to provide the users with the ability to use the app in their native languages.

In this article, we are going to build a React Native app that supports multi-language using [react-native-localize](https://github.com/react-native-community/react-native-localize) package.

## Prerequisites

This tutorial requires basic knowledge of React Native. To set up your development machine, follow the official guide [here](https://facebook.github.io/react-native/docs/0.59/getting-started).

To make sure we are on the same page, following are the versions used in this tutorial -

- Node v10.15.0
- npm 6.4.1
- yarn 1.16.0
- react-native 0.59.9
- react-native-localize 1.1.3
- i18n-js 3.3.0

## Getting Started

We'll be building a React Native app which will support **English**, **French** and **Arabic** language.

> If you want to have a look at the source code right away, here is the Github [link](https://github.com/vikrantnegi/react-native-multi-language-app).

To create a new project using `react-native-cli`, type the following in the terminal:

```bash
$ react-native init multiLanguage
```

```bash
$ cd multiLanguage
```

#### Add required libraries

Install `react-native-localize` by typing the following:

```bash
$ yarn add react-native-localize
```

and then link it using:

```bash
$ react-native link react-native-localize
```

> If you face any error during installation, check the installation instructions [here](https://github.com/react-native-community/react-native-localize#setup).

The `react-native-localize` lib gives you access to a lot of localization related device constants, but does not come with an i18n lib.

We'll use [`I18n.js`](https://github.com/fnando/i18n-js) to provide a I18n translations on the JavaScript.

```bash
$ yarn add i18n-js
```

Since `i18n-js` does not seem to provides any cache / memoization we'll use `lodash.memoize` for the same.

```bash
$ yarn add lodash.memoize
```

## Add Translations

Create a `translations` directory inside `src` and then create, three JSON files as below for each language.

1. `en.json` for English
2. `fr.json` for French
3. `ar.json` for Arabic

Inside these files will be JSON object with keys and values.

Key will the be same for each language and will be used in the app to display text.

The value will be the actual translation that we want to show to the user and will be different for each language.

For English:

```js
{
  "hello": "Hello World!"
}
```

For French:

```js
{
  "hello": "Salut le Monde!"
}
```

For Arabic:

```js
{
  "hello": "أهلاً بالعالم"
}
```

Similarly, you can add more key-value pairs for every text that will be used in the app.

## Add Main Code

Open `App.js` file and the following imports:

```js
import React from "react";
import * as RNLocalize from "react-native-localize";
import i18n from "i18n-js";
import memoize from "lodash.memoize"; // Use for caching/memoize for better performance

import {
  I18nManager,
  SafeAreaView,
  ScrollView,
  StyleSheet,
  Text,
  View
} from "react-native";
```

After that, we'll add some helper functions and constants that we'll use later.

```js
const translationGetters = {
  // lazy requires (metro bundler does not support symlinks)
  ar: () => require("./src/translations/ar.json"),
  en: () => require("./src/translations/en.json"),
  fr: () => require("./src/translations/fr.json")
};

const translate = memoize(
  (key, config) => i18n.t(key, config),
  (key, config) => (config ? key + JSON.stringify(config) : key)
);

const setI18nConfig = () => {
  // fallback if no available language fits
  const fallback = { languageTag: "en", isRTL: false };

  const { languageTag, isRTL } =
    RNLocalize.findBestAvailableLanguage(Object.keys(translationGetters)) ||
    fallback;

  // clear translation cache
  translate.cache.clear();
  // update layout direction
  I18nManager.forceRTL(isRTL);
  // set i18n-js config
  i18n.translations = { [languageTag]: translationGetters[languageTag]() };
  i18n.locale = languageTag;
};
```

Now, we'll create our `App` class component.

```js
export default class App extends React.Component {
  constructor(props) {
    super(props);
    setI18nConfig(); // set initial config
  }

  componentDidMount() {
    RNLocalize.addEventListener("change", this.handleLocalizationChange);
  }

  componentWillUnmount() {
    RNLocalize.removeEventListener("change", this.handleLocalizationChange);
  }

  handleLocalizationChange = () => {
    setI18nConfig();
    this.forceUpdate();
  };

  render() {
    return (
      <SafeAreaView style={styles.safeArea}>
        <Text style={styles.value}>{translate("hello")}</Text>
      </SafeAreaView>
    );
  }
}

const styles = StyleSheet.create({
  safeArea: {
    backgroundColor: "white",
    flex: 1,
    alignItems: "center",
    justifyContent: "center"
  },
  value: {
    fontSize: 18
  }
});
```

In our constructor method, we called `setI18nConfig()` which will set the initial configuration.

Then in `componentDidMount()` we'll add an event listener which will listen for any changes and call `handleLocalizationChange()` if any changes occur.

The `handleLocalizationChange()` method does two things one is that it fires `setI18nConfig()` and `forceUpdate()`. This is necessary for Android devices as the component needs to be re-render for the changes to be visible.

We will remove the listener in `componentWillUnmount()` lifecycle method.

Finally, in `render()` we'll print out `hello` by using `translate()` and passing our `key` as a parameter into it. It will then automatically figure out the language and the text that needs to be shown for that language.

## Running the App

Now its time to see our if the translations are working.

Run your app in simulator or emulator by typing:

```bash
$ react-native run-ios
```

```bash
$ react-native run-android
```

It should be something like this:

![Hello World English](https://thepracticaldev.s3.amazonaws.com/i/cdi7x7lta93kbzjo0t80.png)

Now, change your device language setting to French and open your app again.

![Hello World French](https://thepracticaldev.s3.amazonaws.com/i/smekwd55qpvnlgvewzzo.png)

Similarly, you can change your language setting to Arabic and see hello in Arabic.

So far so great.

But what happens if I choose some random language whose translation is not added in the app? What language will it fall back to?

Well as it turns out the goal of `findBestAvailableLanguage` is to return the best available translation. So It will look at your language preference setting to figure out the fallback language.

If you go to the **Language & Region** setting in your iOS simulator you can see the preference order of the languages.

![Language Preference Setting](https://thepracticaldev.s3.amazonaws.com/i/jwd7qsj50g2rcff925r0.png)

If the language chosen is not in the preferred language `findBestAvailableLanguage` returns `undefined` (so the retained value will be your [fallback](https://github.com/vikrantnegi/react-native-multi-language-app/blob/master/App.js#L25)) because none of the user's preferred languages are available in your translations.

### Bonus

The `react-native-localize` has API that can provides access to lot localization related device constants. Be sure to check out the full APIs available in the [docs](https://github.com/react-native-community/react-native-localize#api).

## Conclusion

Adding multi-language support is that easy. You can now use react-native-localize to easily provide multiple language support in your app which can help in increasing user's app usage.

Find the source code in the Github repo [here](https://github.com/vikrantnegi/react-native-multi-language-app).

> Originally published on [Medium](https://medium.com/better-programming/creating-a-multi-language-app-in-react-native-9828b138c274)

If you like this article, go ahead and show some love and share.