Arabic RTL That Survives Dashboards and Invoices
September 1, 2026 · 8 min read · Belal Nagy
Every project I ship carries Arabic and RTL support — learning platforms, procurement dashboards, financial documents, booking apps. After that many rounds, I can say where RTL actually gets hard, and it is not where tutorials spend their time. Flipping a marketing page is an afternoon. Keeping Arabic correct through data tables, invoices, charts and mixed-direction text is engineering.
This is a field guide to the part after `dir="rtl"` — the decisions that separate an interface that is technically flipped from one an Arabic reader trusts.
Logical properties or a lifetime of overrides
The single highest-leverage decision is writing layout in logical properties from day one: margin-inline-start instead of margin-left, padding-inline-end instead of padding-right, start/end alignment instead of left/right. In Tailwind that means ms-*, me-*, ps-*, pe-* and text-start as reflexes, never their physical cousins.
Do this and 90% of RTL costs nothing — the same stylesheet serves both directions. Skip it and every physical property becomes a future [dir="rtl"] override, and the overrides file becomes its own legacy codebase. I have inherited projects in both states; the difference is weeks.
Bidi text: where trust is won or lost
The genuinely hard problem is mixed-direction content. An Arabic sentence containing a product code, a URL, an email address or an English brand name is a minefield: the Unicode bidi algorithm will happily reorder "ABC-123" or split a phone number across a line in ways that look corrupted to the reader.
The working rules: wrap Latin-script islands — codes, URLs, emails, file paths — in dir="ltr" spans or guard them with bidi isolation (unicode-bidi: isolate, or the ‎ mark where markup is unavailable). Keep phone numbers LTR always. And render user-generated text with dir="auto", because a platform whose users write both Arabic and English will receive both, often in the same field.
Numbers, dates and money
Financial interfaces force decisions marketing pages never meet. Western digits or Eastern Arabic digits? My default is Western digits for anything transactional — amounts, invoice numbers, IBANs — because they match what banks, receipts and calculators show, while Eastern digits remain a locale preference for prose. Whatever the choice, it must be one choice, applied everywhere; mixing digit systems in one document reads as a bug.
Currency and dates go through Intl.NumberFormat and Intl.DateTimeFormat with an explicit locale, never through string concatenation — the position of the currency symbol, the shape of the thousands separator and the order of date parts are all locale decisions that hand-built strings get wrong. An invoice is a legal document; "almost right" formatting is wrong.
Dashboards, tables and charts
Data-heavy screens have a subtlety: the reading direction of the chrome flips, but the direction of data often should not. Table columns mirror, but a column of amounts stays right-aligned in both directions and numbers inside stay LTR. Time axes on charts are the classic trap — most charting libraries assume LTR, and a naively mirrored chart shows time flowing right to left, which no user actually wants. I keep time axes LTR and mirror the legend, tooltips and axis labels instead.
Icons follow meaning, not reflex: arrows that mean "next" or "back" flip with direction; icons depicting real objects — a clock, a play button, a checkmark — never flip. Progress bars fill from the start edge. Getting these details right is invisible; getting them wrong is instantly visible to every native reader.
Fonts and generated documents
Arabic type needs its own font decision, not a fallback stack accident. Arabic glyphs have taller ascenders and deeper descenders than Latin ones, so display type that looks great in English will clip Arabic unless line-height and clamp sizes are tuned per script — my own portfolio headline runs different sizing rules per language for exactly this reason. Cairo, IBM Plex Sans Arabic and Noto family fonts have carried every project of mine well.
Generated documents are the final boss: PDFs, certificates, email templates. HTML-to-PDF pipelines and email clients each have their own bidi quirks, and a certificate with a reversed name or a broken date is a support ticket from someone's proudest moment. Every document template gets rendered and eyeballed in both languages before it ships — there is no shortcut.
Test with real content, not lorem ipsum
RTL bugs hide in real data: the longest Arabic course title, a user named in both scripts, an address containing digits and a Latin street name, a search query mixing directions. Screenshot-diffing key screens in both directions catches regressions, but nothing replaces scrolling actual production-shaped content with the interface in Arabic.
My rule for every feature: it is not done until it has been looked at in Arabic. Not translated later, not flipped later — looked at, in Arabic, before merge. RTL-as-afterthought is how a two-direction product turns into two products.
The takeaway
Logical properties from day one, bidi isolation around every Latin island, one deliberate digit policy, LTR time axes, per-script typography, and both-language review as part of done. None of it is exotic — it is a set of habits. But habits are exactly what distinguish RTL support that demos well from RTL support that four hundred million Arabic speakers can actually trust with their money and their certificates.
Next article
One Django Engine, Three Accredited Platforms