← Back to Blog

The Bidi Trap: Designing Typing Tests That Don’t Break for Arabic/Hebrew

The Bidi Trap: Designing Typing Tests That Don’t Break for Arabic/Hebrew

Why typing tests break for RTL users

If your site includes Arabic or Hebrew passages, you’re already in bidirectional (bidi) territory. Modern Arabic/Hebrew lines often mix right‑to‑left letters with left‑to‑right digits and Latin fragments, and neutral punctuation shifts its allegiance based on context. That’s exactly what the Unicode Bidirectional Algorithm (UAX #9) is designed to handle—but its correct behavior can look counterintuitive in a typing test UI. (unicode.org)

Two quick realities set the stage:

These aren’t bugs—they’re by design. (unicode.org)

The hidden culprits: invisible marks and mirrored punctuation

Unicode defines invisible “direction marks” that behave like zero‑width letters. The classics are LRM (U+200E) and RLM (U+200F); for Arabic contexts there’s also ALM (U+061C). They don’t render, but they nudge neutrals and digits to join the intended side. The Unicode FAQ literally calls them “invisible letters,” and UAX #9 treats them as explicit formatting/mark characters. In a typing test, accidentally including or omitting one can silently add an “error.” (unicode.org)

Mirrored punctuation is another source of confusion. Parentheses, brackets, and some math symbols carry a normative Bidi_Mirrored property. Renderers flip their glyph orientation in RTL runs—there usually isn’t a separate “mirrored character” to type. If your test compares the visual glyph a user sees to a hardcoded character image, you’ll miscount errors; you must compare code points, not pictures. ICU’s own notes emphasize that real mirroring is a renderer/glyph‑selection job. (unicode.org)

Numbers and neutrals inside RTL runs: what actually happens

UAX #9 resolves direction in phases. After setting a paragraph base level, it applies rules W1–W7 for “weak types” (like digits and their adjacent separators) and N0–N2 for neutrals (like most punctuation). A few highlights that routinely bite typing apps:

Those are the algorithm’s rules—not browser quirks. (unicode.org)

Practical example (simplified): suppose your paragraph is RTL and the target text is “سعر 12/05/2026 (تقديري)”. The date’s digits run LTR, and the slashes tend to join the digits per W5/W6; the parentheses mirror visually. If your caret logic assumes “everything goes right‑to‑left,” it will look like the caret jumps “the wrong way” when users type digits or slashes. That’s the bidi rules doing their job. (unicode.org)

Where typing tests go wrong

All three are preventable with bidi‑aware design.

Bidi‑aware prompts that feel natural

Sanitizers and comparators that don’t punish RTL users

Result viewers and caret behavior that make sense

Tiny lab: try these and watch the caret

These are all straight from UAX #9’s rules. (unicode.org)

Quick checklist for implementers

With a small dose of bidi awareness, your Arabic/Hebrew users get a fair test—and you get cleaner data.

Article illustration

Ready to improve your typing speed?

Start a Free Typing Test