<commit_before>---
title: Right-to-Left Layout Support For React Native Apps
author: Mengjue (<NAME>
authorTitle: Software Engineer Intern at Facebook
authorURL: https://github.com/MengjueW
authorImage: https://avatars0.githubusercontent.com/u/13987140?v=3&s=128
category: engineering
---
After launching an app to the app stores, internationalization is the next step to further your audience reach. Over 20 countries and numerous people around the world use Right-to-Left (RTL) languages. Thus, making your app support RTL for them is necessary.

We're glad to announce that React Native has been improved to support RTL layouts. This is now available in the [react-native](https://github.com/facebook/react-native) master branch today, and will be available in the next RC: [`v0.33.0-rc`](https://github.com/facebook/react-native/releases).

This involved changing [css-layout](https://github.com/facebook/css-layout), the core layout engine used by RN, and RN core implementation, as well as specific OSS JS components to support RTL.

To battle test the RTL support in production, the latest version of the **Facebook Ads Manager** app (the first cross-platform 100% RN app) is now available in Arabic and Hebrew with RTL layouts for both [iOS](https://itunes.apple.com/app/id964397083) and [Android](https://play.google.com/store/apps/details?id=com.facebook.adsmanager). Here is how it looks like in those RTL languages:

<p align="center">
  <img src="/react-native/blog/img/rtl-ama-ios-arabic.png" width="280" style="margin:10px">
  <img src="/react-native/blog/img/rtl-ama-android-hebrew.png" width="280" style="margin:10px">
</p>

## Overview Changes in RN for RTL support
[css-layout](https://github.com/facebook/css-layout) already has a concept of `start` and `end` for the layout. In the Left-to-Right (LTR) layout, `start` means `left`, and `end` means `right`. But in RTL, `start` means `right`, and `end` means `left`. This means we can make RN depend on the `start` and `end` calculation to compute the correct layout, which includes `position`, `padding`, and `margin`.

In addition, [css-layout](https://github.com/facebook/css-layout) already makes each component's direction inherits from its parent. This means, we simply need to set the direction of the root component to RTL, and the entire app will flip.

The diagram below describes the changes at high level:

![](/react-native/blog/img/rtl-rn-core-updates.png)

These include:

* [css-layout RTL support for absolute positioning](https://github.com/facebook/css-layout/commit/46c842c71a1232c3c78c4215275d104a389a9a0f)
* mapping `left` and `right` to `start` and `end` in RN core implementation for shadow nodes
* and exposing a [bridged utility module](https://github.com/facebook/react-native/blob/f0fb228ec76ed49e6ed6d786d888e8113b8959a2/Libraries/Utilities/I18nManager.js) to help control the RTL layout

With this update, when you allow RTL layout for your app:

* every component layout will flip horizontally
* some gestures and animations will automatically have RTL layout, if you are using RTL-ready OSS components
* minimal additional effort may be needed to make your app fully RTL-ready

## Making an App RTL-ready

1. To support RTL, you should first add the RTL language bundles to your app.
   * See the general guides from [iOS](https://developer.apple.com/library/ios/documentation/MacOSX/Conceptual/BPInternational/LocalizingYourApp/LocalizingYourApp.html#//apple_ref/doc/uid/10000171i-CH5-SW1) and [Android](https://developer.android.com/training/basics/supporting-devices/languages.html).

2. Allow RTL layout for your app by calling the `allowRTL()` function at the beginning of native code. We provided this utility to only apply to an RTL layout when your app is ready. Here is an example:

   iOS:
    ```objc
    // in AppDelegate.m
  	[[RCTI18nUtil sharedInstance] allowRTL:YES];
    ```

   Android:
    ```java
    // in MainActivity.java
  	I18nUtil sharedI18nUtilInstance = I18nUtil.getInstance();
  	sharedI18nUtilInstance.setAllowRTL(context, true);
    ```<commit_msg>Updating blog post about RTL from setAllowRTL to allowRTL (Android).<commit_after>---
title: Right-to-Left Layout Support For React Native Apps
author: Mengjue (<NAME>
authorTitle: Software Engineer Intern at Facebook
authorURL: https://github.com/MengjueW
authorImage: https://avatars0.githubusercontent.com/u/13987140?v=3&s=128
category: engineering
---
After launching an app to the app stores, internationalization is the next step to further your audience reach. Over 20 countries and numerous people around the world use Right-to-Left (RTL) languages. Thus, making your app support RTL for them is necessary.

We're glad to announce that React Native has been improved to support RTL layouts. This is now available in the [react-native](https://github.com/facebook/react-native) master branch today, and will be available in the next RC: [`v0.33.0-rc`](https://github.com/facebook/react-native/releases).

This involved changing [css-layout](https://github.com/facebook/css-layout), the core layout engine used by RN, and RN core implementation, as well as specific OSS JS components to support RTL.

To battle test the RTL support in production, the latest version of the **Facebook Ads Manager** app (the first cross-platform 100% RN app) is now available in Arabic and Hebrew with RTL layouts for both [iOS](https://itunes.apple.com/app/id964397083) and [Android](https://play.google.com/store/apps/details?id=com.facebook.adsmanager). Here is how it looks like in those RTL languages:

<p align="center">
  <img src="/react-native/blog/img/rtl-ama-ios-arabic.png" width="280" style="margin:10px">
  <img src="/react-native/blog/img/rtl-ama-android-hebrew.png" width="280" style="margin:10px">
</p>

## Overview Changes in RN for RTL support
[css-layout](https://github.com/facebook/css-layout) already has a concept of `start` and `end` for the layout. In the Left-to-Right (LTR) layout, `start` means `left`, and `end` means `right`. But in RTL, `start` means `right`, and `end` means `left`. This means we can make RN depend on the `start` and `end` calculation to compute the correct layout, which includes `position`, `padding`, and `margin`.

In addition, [css-layout](https://github.com/facebook/css-layout) already makes each component's direction inherits from its parent. This means, we simply need to set the direction of the root component to RTL, and the entire app will flip.

The diagram below describes the changes at high level:

![](/react-native/blog/img/rtl-rn-core-updates.png)

These include:

* [css-layout RTL support for absolute positioning](https://github.com/facebook/css-layout/commit/46c842c71a1232c3c78c4215275d104a389a9a0f)
* mapping `left` and `right` to `start` and `end` in RN core implementation for shadow nodes
* and exposing a [bridged utility module](https://github.com/facebook/react-native/blob/f0fb228ec76ed49e6ed6d786d888e8113b8959a2/Libraries/Utilities/I18nManager.js) to help control the RTL layout

With this update, when you allow RTL layout for your app:

* every component layout will flip horizontally
* some gestures and animations will automatically have RTL layout, if you are using RTL-ready OSS components
* minimal additional effort may be needed to make your app fully RTL-ready

## Making an App RTL-ready

1. To support RTL, you should first add the RTL language bundles to your app.
   * See the general guides from [iOS](https://developer.apple.com/library/ios/documentation/MacOSX/Conceptual/BPInternational/LocalizingYourApp/LocalizingYourApp.html#//apple_ref/doc/uid/10000171i-CH5-SW1) and [Android](https://developer.android.com/training/basics/supporting-devices/languages.html).

2. Allow RTL layout for your app by calling the `allowRTL()` function at the beginning of native code. We provided this utility to only apply to an RTL layout when your app is ready. Here is an example:

   iOS:
    ```objc
    // in AppDelegate.m
  	[[RCTI18nUtil sharedInstance] allowRTL:YES];
    ```

   Android:
    ```java
    // in MainActivity.java
  	I18nUtil sharedI18nUtilInstance = I18nUtil.getInstance();
  	sharedI18nUtilInstance.allowRTL(context, true);
    ```
{'fraction_non_alphanumeric': 0.10238616995373752, 'fraction_numerical': 0.028974920866812758, 'mean_word_length': 4.716771050800278, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 26, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1692355', 'n_tokens_mistral': 2594, 'n_tokens_neox': 2387, 'n_words': 911}