People searching RTL localization, bidirectional text, Unicode bidi, Arabic localization QA, Hebrew localization, right-to-left text testing, mixed RTL LTR text, or how to stop numbers and punctuation moving in Arabic and Hebrew UI are usually confronting a display problem that does not behave like ordinary left-to-right translation. Arabic, Hebrew, Persian, Urdu, and other right-to-left writing systems can appear on the same line as left-to-right numbers, Latin product names, URLs, email addresses, file paths, and codes. The logical character sequence can therefore differ from the visual order a user sees.
Current Unicode guidance describes this as bidirectional, or bidi, text. Unicode Standard Annex #9 defines the Unicode Bidirectional Algorithm, while current Unicode documentation identifies directional isolates such as LRI, RLI, FSI, and PDI for keeping one directional run from disturbing surrounding text. Modern web and application frameworks also expose direction-aware markup and layout. The practical search intent is clear: translators and localization teams need to distinguish linguistic direction from visual rendering, test mixed-direction strings with realistic data, and fix the markup or container rather than rearranging characters manually.
This article has one dominant job: build an RTL and bidirectional-text QA workflow that protects natural target-language order while keeping numbers, Latin names, URLs, punctuation, placeholders, and UI layout stable. It does not replace the target-language-script check, which detects the wrong alphabet or unexpected source-language residue. A target can use perfectly correct Arabic or Hebrew characters and still render in the wrong visual order. This page owns directionality: base direction, directional runs, isolates, neutral punctuation, mixed-script tokens, mirroring, layout, and rendered QA.
Quick answer
A reliable RTL/bidi workflow is:
- define the target locale’s base writing direction;
- let the platform’s bidi algorithm handle ordinary text rather than manually reversing characters;
- keep numbers, URLs, email addresses, product codes, and Latin names as logical strings;
- isolate embedded directional runs when surrounding text can reorder them unpredictably;
- prefer semantic markup such as
dir,dir="auto", or dedicated bidi isolation over inserting invisible controls ad hoc; - test punctuation around mixed-direction content;
- test parentheses, colons, slashes, hyphens, plus/minus signs, and currency with realistic runtime values;
- mirror directional layout elements only when the product convention requires it;
- review the rendered UI, not only the CAT editor;
- never “fix” visual order by typing the characters backward.
The central rule is:
store text in logical reading order; let bidi-aware rendering create the visual order.
Logical order and visual order
A left-to-right English sentence is usually easy to imagine:
characters stored left to right.
characters displayed left to right.
An Arabic sentence can be stored in logical reading order while displayed right to left.
Inside that Arabic sentence, a number such as:
2026
still displays left to right.
A Latin product name such as:
AcmeCloud
also has left-to-right direction.
The line therefore contains several directional runs.
The Unicode Bidirectional Algorithm resolves their placement.
Why translators should not reverse text manually
A broken UI can tempt someone to type:
1234
as:
4321
to make it “look right.”
That is a serious mistake.
The stored value becomes wrong.
Different environments may render it differently.
Copy/paste, search, screen readers, and exports can all break.
Fix the directionality mechanism.
Do not corrupt the logical content.
The simplest mental model
A bidi line contains:
- strong RTL characters;
- strong LTR characters;
- numbers;
- neutral punctuation;
- directional formatting/isolation controls.
The renderer considers these classes and their context.
Most ordinary target text requires no manual bidi control.
Problems appear especially where mixed directional content is inserted.
Step 1: set the correct base direction
A page, component, paragraph, or text container needs a base direction.
For an Arabic UI, the base direction is usually RTL.
For an English UI containing one Arabic customer name, the paragraph may remain LTR while the name becomes an RTL run.
Base direction should come from:
- locale;
- semantic markup;
- component logic.
Do not infer it from screen position alone.
Base direction affects punctuation
Consider an Arabic sentence followed by:
: and a Latin code.
The colon is directionally neutral.
Its visual placement depends on nearby strong characters and paragraph direction.
A string that looks correct in an LTR CAT grid can render differently inside an RTL app.
This is why final visual QA matters.
Step 2: use the Unicode bidi algorithm, not visual string manipulation
Unicode UAX #9 is designed to resolve mixed-direction lines.
Frameworks, browsers, and operating systems implement it.
The localization team should work with that algorithm.
Typical fixes involve:
- correct base direction;
- isolation;
- semantic markup;
- component structure.
Not:
- reversed string;
- extra spaces;
- random invisible marks.
Step 3: understand directional isolation
Unicode provides isolate controls such as:
- LRI — Left-to-Right Isolate;
- RLI — Right-to-Left Isolate;
- FSI — First Strong Isolate;
- PDI — Pop Directional Isolate.
The conceptual job of an isolate is:
Treat this embedded text as a self-contained directional unit so it does not influence the ordering of surrounding text, and vice versa.
Web markup such as <bdi> and direction attributes can provide similar semantic isolation.
When isolation helps
Example Arabic target conceptually says:
Account: AcmeCloud-2026
The embedded identifier contains:
- Latin letters;
- hyphen;
- digits.
Without isolation, surrounding punctuation can appear in surprising positions.
If the identifier is treated as one LTR isolate, the line becomes more predictable.
Prefer markup over invisible characters when possible
If the application controls HTML or UI components, semantic direction markup is often easier to:
- review;
- debug;
- maintain.
Invisible Unicode controls can be hard to see in:
- CAT tools;
- code reviews;
- search.
Use control characters when the plain-text format requires them and the pipeline understands them.
Otherwise prefer explicit structure.
Step 4: use dir="auto" or FSI for unknown user-generated direction
A field may display a customer-supplied name.
The application does not know whether the value starts with:
- Arabic;
- Hebrew;
- English;
- digits.
A first-strong heuristic can infer the embedded run’s direction.
This is useful for:
- usernames;
- comments;
- imported titles;
- mixed-language content.
The key word is unknown.
If the application already knows the direction, set it explicitly.
Step 5: do not add direction marks to every RTL string
Most normal Arabic or Hebrew sentences should render correctly when:
- locale is correct;
- container direction is correct.
Blanket insertion of RLM/LRM or isolates can create:
- copy/paste surprises;
- duplicate controls;
- hard-to-debug search mismatches.
Use controls for mixed-direction edge cases, not as universal decoration.
Step 6: test numbers inside RTL text
Numbers often render left to right even inside RTL text.
Test:
- integers;
- decimals;
- percentages;
- phone numbers;
- dates;
- account numbers.
Example:
Arabic text + 15%
The percent sign is neutral or weak in bidi behavior depending on context.
Verify the final display.
Do not assume a screenshot from one browser proves every platform.
Step 7: test decimal and grouping separators
Locale formatting may change:
- decimal separator;
- grouping separator;
- digit shapes.
Directionality can then interact with punctuation.
A numeric value should be produced by locale-aware formatting.
Do not build:
amount + " USD"
as raw text if a proper formatter exists.
Step 8: test currencies
Currency can appear:
- before amount;
- after amount;
- as symbol;
- as code.
Example:
USD 125.50
inside an Arabic sentence contains a strong LTR code and number.
Treat the formatted currency as a coherent unit where practical.
Then place it naturally in the localized message.
Step 9: test dates
A date can contain:
- digits;
- slashes;
- month names;
- punctuation.
An RTL locale may display a date in a visually different order than the source.
Use locale-aware date formatting.
Do not translate a source-formatted date string manually.
Step 10: test phone numbers
Phone numbers are especially confusing in bidi contexts.
Example:
+971 50 123 4567
The plus sign and spaces can interact with RTL surroundings.
Test:
- local;
- international;
- extension.
Keep the stored phone number in the correct logical sequence.
Isolation can help display.
Step 11: test email addresses
Email addresses are LTR technical identifiers even inside RTL prose.
Example:
support@example.com
The @ and periods make visual behavior sensitive to context.
Isolate the email value when the framework supports it.
Do not add spaces inside the email to “fix” display.
Step 12: test URLs
URLs contain:
- scheme;
- colon;
- slashes;
- dots;
- hyphens;
- query parameters.
They should remain valid LTR strings.
A surrounding RTL paragraph can move punctuation visually.
Use <bdi>, dir=ltr, or suitable isolation in the rendered product.
Keep the URL bytes intact.
Step 13: test file paths
Paths such as:
C:\Users\Name\file.txt
or:
/usr/local/bin
are LTR technical strings.
Inside RTL text, backslashes and slashes can look confusing.
Treat them as protected code-like runs.
Step 14: test version numbers and IDs
Examples:
v2.4.10;AB-4821;ISO 9001;SR-009124.
These are identifiers.
The order must remain.
If punctuation appears on the wrong side, fix bidi isolation.
Do not reorder the identifier.
Step 15: test placeholders with mixed-direction runtime data
Target message:
Welcome, {userName}.
If {userName} can be:
- Ahmad;
- John Smith;
- 12345;
- Acme-2026;
the rendered direction changes.
Test several runtime values.
A placeholder is not just a token in the CAT tool.
It is a future directional run.
Step 16: give translators placeholder examples
Developer note:
{ticketId}example: SR-20384
helps the translator understand:
- LTR token;
- expected punctuation;
- likely width.
This context supports better sentence structure.
Step 17: neutral punctuation is where many bidi bugs appear
Characters such as:
- colon;
- semicolon;
- parentheses;
- brackets;
- hyphen;
- slash;
- spaces
may not have a strong direction.
Their placement depends on neighboring runs.
This is why the words can be correct while punctuation looks wrong.
Test punctuation around embedded Latin values.
Worked example 1: label plus code
Concept:
Order ID: AB-4821
In RTL target, the label is RTL.
The ID is LTR.
The colon is neutral.
If the ID is not isolated, the visual result can place the colon unexpectedly.
Correct solution:
- RTL base;
- LTR-isolated ID.
Not:
- manual spaces;
- reversed code.
Step 18: test parentheses
Parentheses are paired punctuation.
The Unicode bidi algorithm can mirror paired brackets in RTL contexts.
Test:
status (Beta)
where:
- status label is Arabic;
Betais Latin.
Depending on markup, parentheses can appear around the wrong visual run.
Isolation improves predictability.
Step 19: do not confuse mirrored glyphs with reversed content
Some punctuation and directional icons mirror visually.
The text inside does not reverse character order.
The renderer chooses the appropriate glyph orientation.
A translator should not replace parentheses manually simply because they look mirrored in RTL.
Step 20: test quotes
Quotation marks around LTR product names can create unusual visual ordering.
Example:
Arabic sentence containing:
“Acme Pro”
Test:
- opening quote;
- closing quote;
- adjacent punctuation.
Use target-locale quotation conventions and bidi-aware rendering.
Step 21: layout direction and text direction are related but separate
An RTL interface may mirror:
- navigation;
- columns;
- alignment;
- icon placement.
Text direction handles characters.
Layout direction handles component arrangement.
A correct Arabic sentence inside a still-LTR layout can feel wrong.
Both need localization testing.
Step 22: mirror directional UI where appropriate
Common elements that may mirror:
- back arrow;
- forward navigation;
- progress flow;
- drawer side.
Elements that may not mirror:
- play icon;
- media transport conventions in some contexts;
- brand logos;
- clock;
- chart axes depending on semantics.
Do not mirror everything automatically.
Use platform guidance.
Step 23: translation is not responsible for icon mirroring
If the back arrow points the wrong way, the translator should report:
- layout/icon bug.
Do not change the word “Back” to compensate.
Route the defect correctly.
Step 24: test alignment
In RTL UI, labels often align right.
But data fields containing:
- email;
- phone;
- URL;
- code
may need LTR alignment or isolation.
Use component-specific behavior.
One alignment rule for the whole screen can be wrong.
Step 25: test forms
A form can contain:
- RTL labels;
- LTR email field;
- LTR password;
- phone number;
- date field.
Each input may have its own direction behavior.
A form is a strong bidi test surface.
Step 26: test search fields
A search query can switch direction depending on user input.
dir=auto can be useful.
Test:
- Arabic query;
- English product;
- numeric code.
The caret and selection behavior matter too.
Step 27: test text editing, not only static display
A string can display correctly after rendering but be painful to edit.
Test:
- cursor movement;
- backspace;
- selection;
- copy/paste;
- insertion around LTR tokens.
This matters for:
- chat;
- comments;
- search;
- profile forms.
Step 28: test copy and paste
Copy a mixed-direction string from the app into:
- plain-text editor;
- browser;
- email.
Does the logical sequence remain correct?
If manual reversal was used, the defect becomes obvious.
A good bidi implementation preserves logical content.
Step 29: test screen readers
Assistive technology should receive:
- logical text;
- meaningful punctuation;
- correct language metadata.
Invisible controls can affect reading.
Test critical mixed-language strings with target-language accessibility tools when possible.
Step 30: language metadata matters
A web element can have:
lang;dir.
They solve different problems.
lang tells software the language.
dir tells direction.
Arabic language does not automatically fix every embedded LTR value.
Use both appropriately.
Step 31: do not use CSS direction as a magic fix for every child
A container-level RTL setting is useful.
Nested code/ID components may need their own isolation.
Understand inheritance.
A single global style can create broken technical tokens.
Step 32: avoid bidi override unless absolutely necessary
Unicode defines directional overrides as well as isolates.
Overrides force characters to behave in a chosen direction.
They are much stronger.
They can make text appear visually reversed.
For normal localization, isolation is usually safer than override.
Use overrides only with expert understanding.
Step 33: isolates are designed to prevent surrounding influence
An embedding can influence surrounding ordering.
An isolate is intentionally more self-contained.
That is why modern Unicode guidance emphasizes isolates for inserted directional text.
When the value is conceptually one embedded entity:
- name;
- URL;
- code;
isolation is a strong default.
Step 34: test first-strong inference carefully
FSI/dir=auto chooses direction based on the first strong character.
What if the string starts with:
- digits;
- emoji;
- punctuation?
The first strong character may occur later.
Test real values.
If the content type is known, explicit direction can be better.
Step 35: emojis can complicate perception
Emoji themselves may be direction-neutral.
An emoji beside:
- Arabic text;
- Latin product name;
- punctuation
can appear on an unexpected side.
Test chat, notification, and social UI where emoji are common.
Step 36: hashtags and @mentions
Social content can contain:
#Product2026;@username.
These are often LTR-ish technical tokens inside RTL prose.
Treat them as coherent entities.
Test punctuation immediately before and after.
Step 37: mixed-script product names
A product name may intentionally combine:
- Arabic;
- English;
- number.
Do not split it into separate directional corrections without brand guidance.
Store the official logical sequence.
Render as one isolated entity where needed.
Step 38: target-only review is not enough for bidi
A CAT target-only view may not reproduce the final application’s direction handling.
Use:
- in-context preview;
- browser/app build;
- device testing.
The final renderer matters.
Step 39: test at several viewport widths
A mixed-direction string can wrap.
Line wrapping changes bidi resolution by line.
A string that looks correct on one line may look confusing across two.
Test narrow mobile screens.
Step 40: test truncation and ellipsis
A UI may truncate:
AcmeCloud-2026...
inside RTL content.
Which side receives the ellipsis?
Does the meaningful identifier remain visible?
Text-overflow behavior needs RTL testing.
Step 41: test tables
Tables combine:
- RTL headers;
- numeric columns;
- IDs;
- dates.
Column alignment can make a correct table hard to read.
Decide:
- text columns right-aligned;
- numeric columns by locale/product convention;
- technical IDs LTR.
Step 42: test charts
Charts can include:
- RTL labels;
- LTR numbers;
- legends.
Do not assume mirroring chart axes is appropriate.
The data model controls chart direction.
Review with domain experts if necessary.
Step 43: test breadcrumb navigation
Breadcrumbs contain directional separators:
Home > Account > Security
An RTL UI may need:
- reversed visual flow;
- mirrored separators.
The logical hierarchy should remain correct.
Use a bidi-aware component.
Step 44: test pagination
Previous/Next controls combine:
- words;
- arrows;
- page numbers.
RTL can change both:
- order;
- icon direction.
Test actual interaction.
Step 45: test keyboard shortcuts
An Arabic menu can display:
- Arabic command;
- Latin shortcut such as
Ctrl+S.
The shortcut should remain readable.
Alignment and isolation matter.
Step 46: test developer console/error output only if user-facing
Internal logs may stay LTR.
Do not spend localization time making developer-only logs aesthetically RTL unless the project requires it.
User-facing errors need proper bidi behavior.
Worked example 2: payment confirmation
Arabic text includes:
- amount
USD 125.50; - card suffix
•••• 4821; - date;
- button.
Test:
- amount order;
- currency placement;
- bullet sequence;
- digit order;
- punctuation;
- alignment.
Payment UI is a good high-risk bidi test.
Worked example 3: account recovery
Arabic sentence:
We sent a code to support@example.com.
The email must stay valid LTR.
The period at sentence end must stay outside the email address.
This is exactly where isolation helps.
Worked example 4: file path
Hebrew help text includes:
C:\Program Files\App\config.json
Without isolation, slashes and colon can look wrong.
Protect the path as one LTR entity.
Do not insert spaces into it.
Failure mode 1: reverse characters manually
Result:
logical content corrupt.
Repair:
renderer direction.
Failure mode 2: global RTL on every child
Result:
URLs and codes render badly.
Repair:
nested isolation/direction.
Failure mode 3: add random LRM/RLM marks until screenshot looks right
Result:
invisible technical debt.
Repair:
semantic markup and reproducible rule.
Failure mode 4: test words but not punctuation
Result:
colons and parentheses jump.
Repair:
mixed-run examples.
Failure mode 5: test static text only
Result:
user-generated values break.
Repair:
runtime examples.
Failure mode 6: mirror every icon
Result:
semantically stable icons become wrong.
Repair:
platform-specific mirror list.
Failure mode 7: CAT preview accepted as final proof
Result:
app rendering differs.
Repair:
real build.
Failure mode 8: bidi issue classified as translation error
Result:
