What you need to know about RTL language support in a mobile app
Imagine: you enter the UAE market, launch an Arabic version of the app — and receive a barrage of negative reviews. The menu is messed up, buttons do not respond, text is truncated.
When launching the app in Arabic, you may encounter that the Back button points right and slides come in from the left. Users are used to the reverse order — and this causes cognitive dissonance.
Without proper RTL support, even a functionally identical app is perceived as broken, leading to a 30% drop in retention (data from our projects). We have adapted more than 20 projects for Arabic and Hebrew and know all the pitfalls. Our team is ready to take on a full audit and turnkey implementation of RTL support.
Simply changing the locale and setting layoutDirection = rtl is only 20% of the work. The rest is manual adaptation of each component: icons, animations, navigation, text, and even gestures (e.g., swipes). Here is what actually breaks:
| Component | iOS | Android | Flutter | React Native |
|---|---|---|---|---|
| Icons | SF Symbols with an RTL variant work, but custom PNG — no | autoMirrored="true" for VectorDrawable, BitmapDrawable is not mirrored |
Directionality does not affect CustomPainter |
I18nManager.isRTL for conditional rendering |
| Animations | UIView.animate with absolute coordinates |
Animator with translationX requires checking layoutDirection |
SlideTransition with initialOffsetX — manual logic |
Animated.timing with useNativeDriver is not mirrored |
| Text | NSTextAlignment.natural is mirrored, .left — no |
textAlignment="viewStart" for TextView |
textDirection: TextDirection.rtl for Text |
textAlign: 'auto' instead of 'left' |
| Navigation | UINavigationController mirrors the Back button automatically |
ActionBar requires android:supportsRtl="true" |
Navigator automatically, but custom transitions — no |
ReactNavigation requires manual setup |
Our approach with custom flipping transforms is 2x faster than the traditional rewriting of all screens for RTL from scratch and reduces rework time by 40%. This makes it possible to save 30–50% of the budget compared to a full rework.
We use automated tests to verify mirroring, which helps identify errors at early stages and reduce QA costs.
Why does a standard RTL solution not cover all cases?
The detailed table above shows typical problems. Let us add that on iOS custom draw() and Core Graphics require conditional flipping to mirror content. On Android autoMirrored works only for VectorDrawable, but not for BitmapDrawable.
In Flutter Directionality does not affect CustomPainter, so you have to manually apply canvas.scale(-1, 1). In React Native, it is important to check the version: on Android I18nManager.isRTL works only in RN >=0.63; otherwise, forceRTL with a reload is needed.
How do we implement RTL support?
- Audit. We launch the app in the Arabic locale via
adb shell setprop persist.sys.locale ar-AE(Android) andSettings → General → Language & Region(iOS Simulator). This reveals 80% of problems. We record artifacts on each screen — on average 10–15 per app out of 50 screens. - Classification. We divide problems into 4 types: layout, icons, text, animations. For each type — its own fix recipe. For example, for icons we use conditional flipping, for animations — replacing absolute coordinates with relative ones.
- Fixes. On iOS, we rewrite custom
draw()for conditional flipping, useUIView.appearance(whenContainedInInstancesOf:)for system inheritance ofsemanticContentAttribute. On Android, we replaceleft/rightwithstart/endin XML and programmatically viaMarginLayoutParamsCompat. For Flutter, we mirrorCustomPainterviacanvas.scale(-1, 1). For React Native — we checkI18nManager.isRTLin each component. - Testing. Necessarily on real devices: Samsung with One UI changes the behavior of
VectorDrawable, and on older iOS versionsUIView.appearancemay not work. We add screenshot tests with RTL locales to CI. We run on 3–4 physical devices to cover 95% of cases.
More about testing
We use XCTest with XCUIRemote to simulate gestures and verify mirroring. On Android — Espresso with DeviceLocale to switch locale. We integrate Firebase Test Lab for testing on real devices in the cloud.
What services are included in RTL adaptation?
- Full audit of code and artifacts on all screens
- Fixing layout, icons, text, animations
- Adaptation of custom components (Canvas, Core Graphics, CustomPainter)
- Setting up backend integration to pass RTL context
- Manual testing on 4+ real devices
- Integration of RTL screenshot tests into CI/CD
- Documentation on RTL support for the team
How long does RTL rework take on each platform?
| Platform | Audit (days) | Fixes (days) | Testing (days) | Total |
|---|---|---|---|---|
| iOS | 1–2 | 2–3 | 1 | 4–6 |
| Android | 1–2 | 2–4 | 1 | 4–7 |
| Flutter | 1 | 1–2 | 0.5 | 2–3.5 |
| React Native | 1 | 2–3 | 0.5 | 3–4.5 |
What typical mistakes are made during RTL development?
- Hardcoded
textAlign: 'left'in custom components instead of'auto'or'start' transform: [{scaleX: -1}]applied to an icon without checkingI18nManager.isRTL— the icon is always mirrored- Number localization:
١٢٣(eastern arabic numerals) vs123— depends on the display context, you need to explicitly setNSLocale/Locale - Bidirectional text (Arabic + English name):
NSAttributedStringwith explicitNSWritingDirectionAttributeName, otherwise word order breaks
How to plan for RTL at the design stage?
The best way is to use start/end instead of left/right from the very beginning, avoid absolute coordinates in animations, and check custom Drawables for autoMirrored. If the project is already ready — we will conduct an audit and eliminate all inconsistencies.
Our engineers guarantee correct operation in Arabic and Hebrew on all supported devices with clean maintainable code.
Do not let your users get lost in a mirrored maze — contact us for a consultation on RTL audit. Order a consultation — we will calculate the timelines and cost. The investment will pay off within 2-3 months after market entry.
Apple recommends using UIView.appearance() for inheriting semantic attributes; for more details, see the RTL (Right-to-Left) article.







