How to add localization (i18n, g11n) and RTL support to a React Native project

Daniel Sternlicht
4 min readNov 13, 2017

--

Let’s face it. If there’s one word that product managers like to say, and give us (all developers) a goosebumps the second we hear it, is “Let’s add LOCALIZATION support(or “Let’s A/B test it”, or “MVP”, well, they say a lot of scary things…).

Although adding the support of multiple languages to your app is extremely important, developing it could become a nightmare.

In this article I’ll walk you through the process of adding localization support to your React Native app. Moreover, we’ll add support to RTL languages (such as Hebrew and Arabic). Just in case.

i18n

In computing, there’s a common term used when discussing localization & internationalization called i18n which is basically the first and last letters in the word internationalization and the 18 characters between them (thanks Wikipedia for that).

We’ll start by adding an internationalization module to our React Native project called react-native-i18n:

npm i react-native-i18n --save

After installing the npm module, you’ll need to link it to your project (see the instructions here).

Locales

In i18n, every language support you want to add to your project called “locale”.

Let’s add a locales folder to our app. This folder will contain JSON files, where each one of them will present a different locale support.

For example, our root folder’s structure could look like this:

ios
android
src
locales
|__ en.json // English
|__ he.json // Hebrew
...

The name of each JSON file should present the language’s code. You may find a list of language codes here.

The structure of the locales’ JSON files is up to you. I found it useful to order them by the screens in the app:

Note: In iOS, after creating the locales, you’ll need to add them in your project’s configuration in Xcode:

Adding localization support in Xcode.

Great. Now that we have the locales set up, it’s time to configure them in our React Native app.

Configuring locales in React Native

We’ll create a new file under the src folder called i18n.js . This file will be our one stop shop for both, defining which locales are supported, and exporting methods and variables we’ll use later in our app.

Here’s how the i18n.js looks like:

What do we have here?

We’re importing ReactNative and I18n modules from the app’s node_modules, then we’re importing the locales we want to support in our app (in our case, en.json for English, and he.json for Hebrew).

Next (line 9), we’re telling the I18n module that in case we didn’t create a locale file for the user’s selected language we allow fallback to English.

In line 12 we’re mapping locale names to the locale JSON files we imported earlier. Note, this is where you’re registering new languages support as well. Adding a JSON file by itself is not enough.

We’re exporting a variable that we could use across our app to specifically handle RTL languages in line 20. Then in line 23 we’re configuring React Native to allow RTL in our app (just in case the selected language is RTL language). This is an extremely important line because it’s a global configuration, meaning, other modules might use this configuration as well.

Line 26 is where the actual magic happen. We’re exporting a method called strings that gets two parameters:

name: A path to the locale string in the JSON file.

params: Parameters we could use in the localized string.

Using localized strings

Everything is basically ready to use. Let’s see how to use the strings function in order to get localized strings.

Here’s how our login screen component looks like before adding localization support:

And here’s how it looks like after adding localization support:

In line 8 we added the i18n.js module that we created earlier, and specifically imported the strings method.

Then we replaced the strings we had (in lines 22–24), and called this method instead. Note that in the login.welcome string (line 22), we passed another parameter called “name” in a JSON format — which will be replaced with the {{name}} parameter we defined in our locale files.

RTL (right-to-left) support

If you want to add RTL support as well, here are few things to keep in mind while developing a React Native app:

  • Flexbox FTW — When you’re laying out your app, always use React Native’s flexbox because it gives you out of the box support for both LTR and RTL. For example, the flex-start property will align items to left in LTR, and to the right in RTL locales.
  • Absolute positioning — If you’re using absolute position in your app, don’t forget to align components to left or right, depending on the locale. In this case, you might want to use the isRTL variable we defined in our i18n.js file and apply left or right styles accordingly.
  • Menus — Another thing to keep in mind is the menus in your app, and more specifically, the drawer menu. You might want to change it’s opening direction for RTL languages.

Bonus — Moment.js localization support

If you’re using Moment.js (A JS module for parsing and manipulating dates and times), you’ll probably want to localize it as well. After some digging I’ve made, I found a simple solution for it.

In the i18n.js file, import the moment module:

import moment from 'moment';

Then, you need to import the relevant locale support from moment’s locale folder. Here’s an example for Hebrew:

require('moment/locale/he.js');

Finally, you need to set the locale globally for Moment.js:

moment.locale('he');

So your updated i18n.js file will look like that:

And…

T-A-D-A-!

Hope this article will help you the next time you need to localize a React Native project.

Comments? Thoughts? Things that I missed? Let me know! 👊

--

--

Daniel Sternlicht

Frontend & Web technologies addict, founder of Common Ninja and There is a bot for that. Check out my personal website at http://danielsternlicht.com :)