Building a site that works in Arabic and English
Bilingual work gets priced as translation and delivered as engineering. These are the decisions that have to happen before the first component is written.
Last reviewed 2026-10-03.
Why this is engineering and not translation
An Arabic version of a site is not the English site with different strings. Arabic runs right to left, so the reading order of the whole interface reverses: navigation, breadcrumbs, table columns, form labels, the direction a carousel advances, the side a sidebar sits on. The text is also cursive, which means letters join and change shape depending on their neighbours. Several things front end developers do without thinking break that.
The cost of getting this wrong is not a bad looking page. It is a rebuild, because direction ends up hardcoded in dozens of components and every one of them has to be opened again. The W3C's introduction to scripts and direction is the shortest accurate background if your team has not done this before.
URLs, hreflang and the thing Google needs
Pick one URL strategy and never mix them. A subdirectory, /ar/, is the usual right answer: it inherits the domain's authority, it is cheap to host, and it keeps one deployment. A subdomain is defensible when the Arabic site is run by a different team with a different stack. A separate country domain only makes sense when the Arabic site is genuinely a different business.
Whichever you choose, every page needs reciprocal annotations pointing at each of its language versions, including itself, and a default for users whose language you have not matched. Google's documentation on localised versions is the authority on the mechanics. Three failures account for almost every broken implementation in this market.
- Annotations that are not reciprocal. If the English page points at the Arabic page, the Arabic page must point back, or the pair is ignored.
- A language tag that is really a guess. Use ar for Arabic generally and a region only when the content is genuinely regional, for example ar-AE where prices and terms are specific to the UAE.
- No default entry, so a visitor whose language you do not publish gets whatever the crawler happened to pick.
Do not auto redirect by browser language or IP. It traps the substantial share of UAE residents who read English in Arabic pages, or the reverse, and it confuses crawlers. Detect, suggest, let the person choose, and remember the choice.
Direction belongs to the document and the component
The dir attribute on the html element sets the base direction of the page, and lang tells the browser and screen readers which language they are dealing with. Both are required. Set dir on html, not on body, so that scrollbars and dialogs inherit it.
Document level direction is not sufficient on its own, because real pages mix scripts. An Arabic paragraph that contains an English product name, a code snippet, a phone number or a URL will render with punctuation in the wrong place unless the embedded run carries its own direction. The fix is to mark the embedded run rather than to fight it with spaces: give it dir="ltr" and, where the surrounding flow needs isolating, use the bidirectional isolation that CSS and HTML provide for exactly this case. User generated content is where this bites hardest, because you cannot predict the script.
In a component library, prefer styling against direction rather than duplicating components. The :dir() pseudo class lets one stylesheet describe both directions, which keeps a single source of truth for anything that genuinely cannot be expressed logically, such as a chevron.
The CSS rule that removes most of the work
Almost all of the layout work disappears if the stylesheet stops talking about left and right and talks about start and end instead. CSS logical properties map to physical sides based on the element's writing mode and direction, so the same declaration produces a mirrored layout in Arabic with no override.
| Instead of | Use | Why it matters |
|---|---|---|
| margin-left, padding-right | margin-inline-start, padding-inline-end | Spacing follows reading order instead of the screen |
| left, right in positioning | inset-inline-start, inset-inline-end | Badges, close buttons and tooltips land on the correct side |
| text-align: left | text-align: start | The single most common cause of ragged Arabic paragraphs |
| border-left | border-inline-start | Quote bars and active navigation markers flip correctly |
| width, height on flow | inline-size, block-size | Consistent with the rest of the logical model |
Flexbox and grid already follow the inline axis, so rows, gaps and grid placement mirror on their own. Explicit left and right values are what stop them.
This is worth adopting on a site that has no Arabic version yet. It reads the same, it costs nothing, and it converts a future bilingual project from a rewrite into a content task.
What must not be mirrored
Mirroring is not universal, and over mirroring looks as wrong as not mirroring at all. The reliable test is whether the thing carries meaning tied to the real world or to reading order.
- Mirror: anything about sequence or progress. Back and forward arrows, breadcrumb separators, progress bars, carousel controls, sliders, indentation, the side the sidebar sits on.
- Do not mirror: logos, photographs, product images, play and pause controls, clock faces, map pins, checkmarks, and anything with text baked into it.
- Numbers stay left to right even inside Arabic text. A phone number, a price or a version string does not reverse.
- Charts are a judgement call. Mirror the axis if the chart reads as a sequence; leave it if it reads as a picture. Keep it consistent across the site either way.
Shadows and gradients are the detail usually missed. A drop shadow that implies a light source from the top left should keep implying it. An offset that is part of a component's structure, such as a stacked card edge, should flip.
Arabic typography, and the one property to never use
Arabic needs its own font stack. A Latin font with an Arabic fallback produces mismatched weight and height, and the browser's default Arabic fallback differs on every platform, so the page you approve is not the page half your audience sees. Choose an Arabic family deliberately and pair it with the Latin one, checking that digits and punctuation look like they come from the same design.
Then there is the rule that matters most and is broken most often: never apply letter-spacing to Arabic text. Arabic letters join, and letter spacing inserts gaps between joined forms, which breaks words apart. If your design system sets a tracking value on headings globally, it has to be reset for Arabic.
- Arabic glyphs are taller and have deeper descenders, so Arabic usually needs more line height than the same size of Latin text, not less.
- Avoid synthesised bold. If the Arabic family has no bold weight, the browser will smear the regular one. Load a real weight or choose another family.
- Avoid all caps styling, which has no meaning in Arabic, and avoid small caps for the same reason.
- Set a slightly larger base size for Arabic if testing shows it, and keep it as a direction scoped override rather than a separate stylesheet.
- Watch for diacritics in religious or educational content. They add height and can clip against tight line boxes.
Numerals, currency and dates
Two numeral systems are in use: Western digits and Arabic-Indic digits. Which one is expected depends on the audience and the type of content, so this is a decision to make with the client rather than a default to inherit from a library. Decide once, apply everywhere, and make it explicit in code rather than accidental.
Use the platform formatting APIs rather than string concatenation. Intl.NumberFormat takes a locale and a numbering system, so an ar-AE locale can be forced to Western digits where that is the house style, and currency formatting puts the dirham symbol and the separators where that locale expects them. The equivalent date API handles the Hijri calendar, which some audiences expect alongside the Gregorian date rather than instead of it.
- Never hardcode a currency string in a template. Format it.
- Never reverse a number to make it look right. If it looks wrong, the direction of the surrounding run is wrong.
- Check sorting. Alphabetical order in Arabic is not the order your database returns by default.
- Check search. Arabic has variant forms of the same letter and optional diacritics, so a naive exact match will miss results a user considers identical. Normalise on both index and query.
Forms, names and addresses
Forms are where bilingual sites lose conversions quietly. The input itself needs its own direction handling, because a user may type Arabic into a field whose placeholder is English or the reverse, and the caret has to behave. Validation messages have to exist in both languages and have to be as specific in Arabic as in English, which machine translation rarely achieves.
- Do not split names into first and last and then require both. Many names in this region do not decompose that way.
- Accept a phone number with or without the country code and normalise server side. A regex that demands one format rejects real customers.
- Addresses in the UAE do not have a postal code in the sense most form libraries assume. A required postcode field is a dead end.
- Keep the submitted language with the record, so the reply goes out in the language the person used.
- Mirror the error summary position along with the form, and keep focus management working in both directions.
A bilingual QA pass that takes an hour
Most defects in this area are caught by a short, repeatable pass. Run it on every release, not at the end of the project.
- Load every template in Arabic at a narrow width and look for anything pinned to the wrong side.
- Search the stylesheet for left, right, margin-left and text-align: left. Each hit is either deliberate or a bug.
- Put an English product name inside an Arabic sentence and check the punctuation lands correctly.
- Check one page with a screen reader to confirm lang and dir are announced and the reading order is sane.
- Confirm the Arabic font is actually loading rather than falling back, on one Apple device and one Android device.
- Validate that every page carries reciprocal language annotations and that the default entry exists.
- Submit the form in Arabic and read the email that arrives.
Frequently asked questions
Is a subdirectory or a subdomain better for an Arabic version?
A subdirectory such as /ar/ is the usual right answer. It inherits the domain's authority, keeps one deployment and one build pipeline, and makes reciprocal language annotations trivial. Use a subdomain only when a different team runs the Arabic site on a different stack, and a separate country domain only when it is genuinely a different business.
Can I just add dir="rtl" to make a site work in Arabic?
It sets the base direction, which is necessary but not sufficient. Any component whose stylesheet names left or right will stay where it was, embedded English runs inside Arabic text will still render punctuation incorrectly without their own direction, and the font stack and line height will still be wrong. The attribute is step one of several.
Why does Arabic text look broken with gaps between letters?
Almost always letter-spacing applied by a global heading or button style. Arabic letters join, so inserting tracking splits words. Reset it for Arabic text rather than removing it from the design system.
Should Arabic pages use Arabic-Indic numerals?
It depends on audience and content type, and both are in use in the UAE. Decide it explicitly with the client, implement it through the locale and numbering system in the formatting API rather than by substituting characters, and apply the same choice across prices, dates and phone numbers.
Can machine translation produce the Arabic version?
It can produce a draft, and it regularly produces confident, wrong output in exactly the places that cost money: product names, legal terms, calls to action and error messages. Treat it as a first pass that a human editor who knows the business owns, and keep the editing loop inside the content system rather than in spreadsheets.
Does Arabic content need separate SEO work?
Yes, because the queries are not translations of each other. Arabic searchers use different phrasings, and spelling variants and diacritics mean a keyword list translated word for word will miss the terms people actually type. Research the Arabic terms natively, then write for them rather than translating the English page.