RTL app localization fails when a team treats direction as a switch that reverses text and nothing else. The labels may align to the right while back buttons, progress indicators, swipe actions, charts, and mixed-language values still behave like an English interface. The result is not one visual defect. It is a set of conflicting spatial rules. Build direction into layout semantics, classify what should mirror, isolate bidirectional text, and test every interaction in both directions. Android's guidance on supporting different languages and cultures provides the platform mechanics. This guide turns those mechanics into an implementation and verification plan.
Use semantic direction, not a screen-wide flip
A reliable right-to-left layout follows five rules:
- Resolve one interface direction from the active app locale.
- Position adaptable controls with logical start and end edges.
- Mirror only assets and motion whose meaning depends on reading direction.
- Isolate user-generated or mixed-direction text from surrounding layout.
- Run the same navigation and regression tests in one LTR locale and one RTL locale.
Logical edges and physical coordinates are not interchangeable. A practitioner question about Android RTL layout direction behavior reports that getX() still measures from the physical left after the layout changes to RTL. A physical coordinate API continues to use its documented origin. Layout direction changes how semantic edges resolve; it does not create a new coordinate system. Code that assumes otherwise will fail in drag calculations, animations, overlays, and hit testing.
Treat direction as application state with a clear owner. A component may read that state to select a logical constraint or a directional asset, but it should not infer direction from the text currently displayed inside it.
Why partial mirroring produces inconsistent UI
Three different concepts are often collapsed into one boolean.
Text direction
Text direction controls how characters and inline runs are ordered. Arabic or Hebrew text can contain Latin product names, email addresses, numbers, and code. The Unicode bidirectional algorithm handles much of this, but dynamic content still needs an appropriate base direction and isolation.
Layout direction
Layout direction controls where logical start and end edges appear. In LTR, start normally resolves left. In RTL, start normally resolves right. This affects alignment, padding, row order, navigation affordances, and placement of secondary actions.
Semantic direction
Semantic direction belongs to the content itself. A timeline, media control, compass, clock, mathematical symbol, or brand mark may have a fixed meaning that should not reverse with reading order. A back arrow or ordered step progression often is reading-direction dependent. A play icon or company logo normally is not.
A blanket transform cannot distinguish those categories. It also transforms text and images that should remain intact. Apple's right-to-left interface guidance is a useful platform reference for deciding how navigation and controls should adapt. The implementation still needs an explicit asset policy because an image pipeline cannot infer semantic meaning from pixels.
Build an RTL app localization direction model
Start with one resolved value rather than scattered checks for Arabic or Hebrew language codes.
type InterfaceDirection = 'ltr' | 'rtl'
type LocaleContext = {
locale: string
direction: InterfaceDirection
}
type DirectionalAssetPolicy =
| 'mirror-in-rtl'
| 'fixed-orientation'
| 'locale-specific'
function edge(
direction: InterfaceDirection,
logical: 'start' | 'end'
): 'left' | 'right' {
if (logical === 'start') return direction === 'rtl' ? 'right' : 'left'
return direction === 'rtl' ? 'left' : 'right'
}
Resolve LocaleContext when the user selects an app locale or when the app accepts a supported system locale. Keep that decision separate from the device region and separate from the direction of an individual message. A user can run an English interface while reading Arabic content, or use an Arabic interface while entering a Latin email address.
Do not persist a second direction preference unless the product genuinely lets users override it. Duplicate locale and direction settings can disagree. Derive the interface direction from the resolved supported locale, then pass the result through the same context used by layout and navigation components.
Replace physical layout properties
Audit components for physical names such as left, right, marginLeft, paddingRight, leftIcon, and slideFromLeft. Decide whether each use represents a semantic edge or a fixed coordinate.
Use logical properties for ordinary UI flow:
.card {
padding-inline-start: 1rem;
padding-inline-end: 1rem;
border-inline-start: 0.25rem solid var(--accent);
text-align: start;
}
.notification-action {
margin-inline-start: auto;
}
On Android, migrate adaptable constraints and spacing to start and end. The official Android guide documents android:supportsRtl, the precedence of start and end attributes, layout mirroring, drawable handling, and the Force RTL developer option. Do not enable RTL support and assume the migration is finished. Physical attributes can remain in custom views, old XML, drawing code, animation offsets, and third-party wrappers.
Keep physical coordinates where the domain is physical. Canvas geometry, map coordinates, touch locations, and screen captures may still use left-origin coordinates. Convert between semantic edges and physical values at a named boundary. That makes the conversion visible during review instead of hiding it inside arithmetic.
Classify icons and visual content
Create an asset inventory with a required mirroring policy. Do not leave the choice to each screen.
| Asset or control | Default policy | Reason to review |
|---|---|---|
| Back and forward arrows | Mirror in RTL | Meaning follows navigation and reading progression |
| Ordered step chevrons | Mirror in RTL | Sequence flows from the logical start edge |
| Undo and redo | Review by platform | Shape and convention can be platform specific |
| Play, pause, camera, search | Fixed orientation | Meaning is not based on text direction |
| Logos and wordmarks | Fixed orientation | Mirroring changes the identity |
| Screenshots containing UI text | Locale specific | Both language and embedded direction may differ |
| Charts and timelines | Product decision | Time order and axis meaning can be fixed or localized |
Store the policy beside the asset component or design-system token. For a directional icon, expose a semantic name such as BackIcon rather than letting callers import a generic left arrow. The semantic component can select the correct orientation from LocaleContext.
Review gestures with the same policy. A swipe that means dismiss, reveal actions, move through history, or advance onboarding may depend on the component's logical start and end. A drag tied to a physical canvas does not. Document the meaning before changing the sign of an offset.
Isolate mixed-direction text
RTL screens regularly contain LTR fragments: account IDs, URLs, email addresses, file paths, version numbers, and untranslated brand names. Their punctuation can move when the surrounding paragraph provides the wrong base direction.
W3C's guide to inline markup and bidirectional text explains how inline markup can control or isolate bidirectional runs in HTML. For web content, use semantic direction attributes and isolation elements for dynamic values instead of inserting invisible direction characters throughout application strings. For native UI, use the platform's bidirectional text APIs and mark the base direction of the value at its rendering boundary.
Keep translators out of layout markup when possible. A localized message should own sentence order and placeholders, but a reusable account-ID component should own isolation for the value it renders. This division prevents each translation from carrying fragile directional control characters.
Test mixed text with realistic examples, not only a pure Arabic sentence. Include an Arabic sentence with a Latin product name, an email address followed by punctuation, a phone number, a URL, and an interpolation at the beginning and end of a message.
Make transitions follow navigation meaning
Animations often expose direction bugs after static screenshots look correct. Name transitions by intent: push-detail, pop-detail, open-drawer-at-start, and reveal-end-actions. Avoid names such as slide-left unless movement must remain physically left.
Calculate the physical animation vector once from the semantic transition and current direction. Use the same resolved direction for the outgoing and incoming views. If locale changes are allowed while the app is open, finish or cancel active transitions before rebuilding direction-sensitive navigation state. Mixing two direction values inside one animation can leave views on the wrong side or reverse an interactive gesture midway.
For navigation history, keep the stack order unchanged. Direction affects presentation and gesture mapping, not which screen is the previous screen. This rule prevents a visual mirror from becoming a data-structure reversal.
Handle direction changes and failure states
An app can receive a new locale at startup, account switch, settings update, or operating-system change. Define one policy for when direction takes effect. Many products can rebuild the root UI after the user confirms a language change. That is safer than mutating hundreds of mounted components independently.
Before applying a direction change:
- Validate that the locale is supported.
- Load the required localized resources.
- Resolve its interface direction.
- Close or preserve transient UI according to product policy.
- Recreate direction-sensitive navigation and layout state.
- Record a safe diagnostic event if the rebuild fails.
If localized resources fail to load, keep the previous complete locale and direction together. Do not combine old RTL text with a newly selected LTR layout or the reverse. A language change is one state transition, so resource readiness and direction readiness should commit together.
Third-party components need a containment plan. Wrap a component that assumes left and right, translate semantic inputs at the wrapper boundary, and add RTL screenshots and interaction tests around it. If it cannot support the required behavior, replace it or explicitly exclude the feature from RTL locales. A silent half-working control is not a fallback.
Verify both directions with one test matrix
Begin with a small matrix that pairs one LTR locale with one RTL locale and exercises the same scenarios. Force RTL can reveal layout assumptions, but it does not replace testing translated content because English text does not reproduce Arabic shaping or mixed-direction runs.
Use this checklist for each release-critical screen:
- The first focusable item starts at the expected logical edge.
- Primary and secondary actions retain their intended hierarchy.
- Back, forward, disclosure, and ordered-step icons follow the asset policy.
- Logos, media controls, and fixed-orientation symbols do not mirror accidentally.
- Drawers, sheets, menus, and swipe actions open from the intended semantic edge.
- Push and pop transitions agree with interactive gestures.
- Long Arabic or Hebrew labels wrap without covering adjacent controls.
- Email addresses, URLs, numbers, and placeholders remain readable in surrounding RTL text.
- Screen-reader focus order follows task order rather than raw visual coordinates.
- Switching back to an LTR locale restores layout, assets, and motion without restarting from stale state.
Add assertions below screenshots. A screenshot can reveal spacing and icon direction, while an interaction test verifies that a swipe or tap performs the correct action. For coordinate-heavy components, test the conversion function directly with the same logical input in both directions.
A compact regression fixture should include a list-detail flow, a form with validation, a menu or drawer, a card with trailing actions, a progress sequence, and a mixed-direction message. These components cover most places where semantic and physical direction diverge.
Common RTL implementation mistakes
A common mistake is replacing every left with right. That preserves the physical-coordinate model and creates another code path to maintain. Replace semantic uses with start and end, and leave genuinely physical uses explicit.
Another mistake is mirroring all images in a parent transform. Text, logos, product screenshots, media controls, and charts can become incorrect. Mirror a reviewed directional asset at its own boundary.
Teams also test Arabic copy inside an LTR shell and call the result RTL support. Arabic and Hebrew labels also change length, so the same screens need the text expansion and UI overflow checks that any other locale gets. Text alignment is only one layer. Navigation, focus order, gestures, overlays, transitions, and mixed content need the resolved interface direction too.
Do not rely only on a platform's forced-direction developer setting. It is useful for finding structural assumptions, but it cannot validate translated string length, Arabic shaping, punctuation around dynamic values, or locale-specific imagery. Use forced direction early, then run the complete matrix with a real supported RTL locale.
Start with a direction audit
For the next RTL app localization change, inventory every physical left or right reference in one release-critical flow. Classify each as logical layout, fixed geometry, directional asset, or motion. Convert only the logical cases, add an explicit policy for each asset and gesture, then run that flow in Arabic or Hebrew and in English. This single audited path becomes the reference implementation for the rest of the app.
References
- Android: Support different languages and cultures: Supports logical start and end attributes, RTL application configuration, layout mirroring, drawable handling, and testing guidance.
- Apple: Right to left: Supplies platform design guidance for interfaces that adapt to right-to-left reading order.
- W3C: Inline markup and bidirectional text in HTML: Explains inline direction and isolation for mixed-direction web text.
- Stack Overflow: Android RTL layout direction behavior: Provides a practitioner report about confusing semantic layout direction with physical X coordinates.
