Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forced RTL in Brownfield Apps Due to android:supportsRtl="true" Requirement in React Native 0.75+ #50500

Open
YOEL311 opened this issue Apr 6, 2025 · 4 comments
Labels
Needs: Attention Issues where the author has responded to feedback. Platform: Android Android applications. Type: Unsupported Version Issues reported to a version of React Native that is no longer supported

Comments

@YOEL311
Copy link

YOEL311 commented Apr 6, 2025

Description

In React Native 0.75, a breaking change requires android:supportsRtl="true" in the Android manifest. This change causes issues for brownfield applications that integrate React Native into an existing Android app with a mix of LTR and RTL layouts.

Our application consists of:

  • Old native screens written in Java/Kotlin with XML layouts that are designed in LTR order.
  • New React Native screens written with RTL order.

Before React Native 0.75, the RTL configuration worked as expected. However, since this change:

  • If android:supportsRtl="false" is set (or omitted), React Native incorrectly lays out some components in LTR instead of RTL.
  • If android:supportsRtl="true" is set, the entire app (including old native XML screens) is forced into RTL, which breaks the native LTR layouts.

This behavior only occurs when the device language is set to an RTL language (e.g., he-IL). The issue happens because when android:supportsRtl="true", the direction of LinearLayout and other native views is automatically set to RTL based on the device locale.

Code Reference

The issue appears to be caused by the following logic in I18nUtil.kt:

in this commit
82c6f8a
this PR
#44538

📂 Path:
packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/I18nUtil.kt

private fun applicationHasRtlSupport(context: Context): Boolean {
    return (context.applicationInfo.flags and ApplicationInfo.FLAG_SUPPORTS_RTL) != 0
}

public fun hasRtlSupport(context: Context): Boolean {
    return applicationHasRtlSupport(context) || isRTLAllowed(context)
}

While this code is not part of Yoga, Yoga may be observing this behavior, leading to the layout inconsistencies.

Expected Behavior

There should be a way to enable RTL only for React Native screens while keeping old native screens unchanged.

Actual Behavior

React Native forces either:

  • LTR mode for React Native screens when android:supportsRtl="false", which is incorrect.
  • RTL mode for the entire app when android:supportsRtl="true", which breaks old native LTR screens.

Possible Solutions

  • Provide an override mechanism in React Native to allow RTL rendering without requiring android:supportsRtl="true".
  • Allow setting RTL only at the React Native level instead of enforcing it globally through the Android manifest.
  • If no other solution is possible, I am willing to submit a patch to address this issue. However, when I attempted to do so, I couldn't modify the relevant code because it is brought into my project as a compiled dependency.

Steps to reproduce

install app

React Native Version

0.78.0

Affected Platforms

Runtime - Android

Output of npx @react-native-community/cli info

`
System:
  OS: macOS 15.3
  CPU: (12) arm64 Apple M3 Pro
  Memory: 156.27 MB / 18.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 21.7.3
    path: ~/.nvm/versions/node/v21.7.3/bin/node
  Yarn:
    version: 1.22.22
    path: /opt/homebrew/bin/yarn
  npm:
    version: 10.5.0
    path: ~/.nvm/versions/node/v21.7.3/bin/npm
  Watchman:
    version: 2025.03.10.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.15.2
    path: /usr/local/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.2
      - iOS 18.2
      - macOS 15.2
      - tvOS 18.2
      - visionOS 2.2
      - watchOS 11.2
  Android SDK:
    API Levels:
      - "28"
      - "30"
      - "31"
      - "33"
      - "34"
      - "35"
    Build Tools:
      - 30.0.3
      - 33.0.0
      - 33.0.1
      - 34.0.0
      - 35.0.0
    System Images:
      - android-35 | Google Play ARM 64 v8a
    Android NDK: Not Found
IDEs:
  Android Studio: 2024.2 AI-242.23339.11.2421.12700392
  Xcode:
    version: 16.2/16C5032a
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.13
    path: /Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/bin/javac
  Ruby:
    version: 2.6.10
    path: /usr/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.72.17
    wanted: 0.74.7
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: false
`

Stacktrace or Logs

non

Reproducer

https://github.com/YOEL311/reproduceRN-RTL

Screenshots and Videos

No response

@react-native-bot react-native-bot added the Type: Unsupported Version Issues reported to a version of React Native that is no longer supported label Apr 6, 2025
@react-native-bot
Copy link
Collaborator

Warning

Unsupported version: It looks like your issue or the example you provided uses an unsupported version of React Native.

Due to the number of issues we receive, we're currently only accepting new issues against one of the supported versions. Please upgrade to latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If you cannot upgrade, please open your issue on StackOverflow to get further community support.

@react-native-bot
Copy link
Collaborator

Warning

Unsupported version: It looks like your issue or the example you provided uses an unsupported version of React Native.

Due to the number of issues we receive, we're currently only accepting new issues against one of the supported versions. Please upgrade to latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If you cannot upgrade, please open your issue on StackOverflow to get further community support.

@YOEL311
Copy link
Author

YOEL311 commented Apr 6, 2025

This also occurs in the 0.78 version
It started at version 0.75

@github-actions github-actions bot added Needs: Attention Issues where the author has responded to feedback. and removed Needs: Author Feedback labels Apr 6, 2025
@NickGerleman
Copy link
Contributor

In the previous state, where RN would ask Yoga to layout in RTL, but android:supportsRtl="false", users in RTL locale could get subtle bugs (e.g. switches being drawn in LTR, even in RTL layouts, scroll indicators being shown on the wrong side of the screen, etc). That is because Yoga may layout elements in RTL based on locale, but any native views within the hierarchy would then get the wrong treatment when drawing or doing their own layout.

More recent versions of RN do some work to keep these synchronized, so that if part of the RN tree is RTL, any Android components are also rendered in RTL. But this depends on the Android application having some RTL awareness. I.e. there will not be an option going forward to perform Yoga layout in RTL, when the general Android layout is unaware of layout direction.

If you want to enable application-level RTL awareness, but keep old Android screens incompatible with RTL, displaying as LTR, one option could be to set android:layoutDirection="ltr" (or similar) on existing native views.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs: Attention Issues where the author has responded to feedback. Platform: Android Android applications. Type: Unsupported Version Issues reported to a version of React Native that is no longer supported
Projects
None yet
Development

No branches or pull requests

3 participants