A bilingual site in English and Arabic or Urdu is not just a translation project. Right-to-left languages flip the direction of the whole interface, change how text is set, and need their own search setup. Done as an afterthought, it shows immediately. Here is how to do it properly, drawing on what we learned building the English and Urdu website for Pak Palestine Forum.
Decide the URL structure first
Each language needs its own crawlable URL, for example /en/about and /ur/about. Switching language only with a cookie or a script means search engines see one version and never index the other.
Translate each page fully, including titles, meta descriptions, image alt text, and form messages, and make the language switcher link to the equivalent page in the other language rather than the home page. Then connect the versions with hreflang annotations, in both directions, plus an x-default for visitors whose language you do not serve. Each language version should canonicalise to itself, never to the English page.
Set direction at the document level
The single most important line is the html element: lang="ur" dir="rtl" for the Urdu version, lang="en" dir="ltr" for English. With direction set at the root, the browser does a great deal of work for you. Text aligns to the right, table columns run right to left, and flexbox rows and grid columns follow the reading direction automatically.
Most RTL bugs come from code that overrides this by hard-coding a physical direction: text-align: left, float: right, or an absolutely positioned element pinned to left: 0. Search the codebase for these early, because each one becomes a mirror-image bug in the other language.
Use logical CSS properties
Logical properties describe layout in terms of the reading direction instead of the physical screen. Start and end mean left and right in English, and right and left in Urdu or Arabic, so one stylesheet serves both.
| Physical property | Logical equivalent |
|---|---|
| margin-left | margin-inline-start |
| padding-right | padding-inline-end |
| left: 0 | inset-inline-start: 0 |
| text-align: left | text-align: start |
| border-left | border-inline-start |
Utility frameworks support this too. Tailwind CSS, for example, has logical spacing utilities (ms-, me-, ps-, pe-) and start- and end- positioning, plus rtl: and ltr: variants for the rare cases where a style genuinely needs to differ by direction.
What to mirror and what not to
Mirroring is not flipping the whole page like an image. Elements that express direction or sequence should mirror. Elements that represent real-world objects or fixed conventions should not.
- Mirror: navigation order, back and forward arrows, breadcrumb chevrons, sidebars and drawers, progress steps, carousels, and the placement of form labels and icons inside inputs.
- Do not mirror: logos and brand marks, media controls such as play and fast-forward, maps, clocks, phone numbers, email addresses, and code.
- Charts deserve a deliberate decision. Many readers expect a time axis to keep running left to right even in an RTL interface.
Typography for Arabic script
Urdu is traditionally set in the Nastaliq style, which flows diagonally and stacks letters vertically. A widely used free web font is Noto Nastaliq Urdu. Arabic is usually set in Naskh or a modern sans style, such as Noto Naskh Arabic or Noto Sans Arabic.
Arabic-script text generally needs a larger font size than the Latin text beside it to read comfortably, and Nastaliq in particular needs generous line height, or its tall forms collide between lines. Never apply letter-spacing to Arabic script: the letters are joined, and spacing breaks the connections. Arabic-script fonts are also large files, so subset them and use font-display: swap to keep pages fast.
Mixed-direction text, numbers, and forms
Real content mixes directions constantly: an English brand name inside an Urdu sentence, a phone number, an email address, a price. The browser's bidirectional algorithm handles most of this, but it needs help at the edges.
- Use dir="auto" on inputs and on user-generated content such as comments, so each one takes the direction of its own text.
- Wrap inserted text of unknown direction, such as usernames, in a bdi element so it cannot scramble the surrounding sentence.
- Keep email, phone, URL, and code fields left-to-right with dir="ltr", even on the RTL version.
- Decide whether to show Western digits or Eastern Arabic digits, and format consistently with Intl.NumberFormat and Intl.DateTimeFormat.
- Translate validation and error messages too. A form that shows English errors on an Urdu page breaks trust at the moment it matters most.
Components and libraries
Check every interactive component in both directions before choosing it. Sliders, date pickers, carousels, and drawers are the usual offenders. Radix UI, which we used on the Pak Palestine Forum site, supports reading direction through its DirectionProvider, so menus, sliders, and other primitives behave correctly in RTL. Map libraries such as Leaflet render maps normally, which is what you want, but their surrounding controls and popups still need RTL styling.
SEO for bilingual websites
- One URL per language, with reciprocal hreflang annotations and an x-default.
- A self-referencing canonical on every language version.
- Translated titles, meta descriptions, headings, and alt text, written for how people actually search in that language, not machine-translated from English.
- Both language versions listed in the sitemap.
- Structured data with inLanguage set correctly on each version.
Remember that search behaviour differs by language. Many Urdu speakers search in English or in Roman Urdu, so keyword research for the Urdu version should check all three.
A testing checklist
- Switch every page to the other language and compare layouts side by side.
- Tab through each page and confirm keyboard focus moves in the reading direction.
- Run a screen reader on the RTL version and confirm it announces the right language.
- Test long words and long translations for overflow and truncation.
- Submit every form with valid and invalid input in both languages.
- Check mixed content: brand names, numbers, emails, and links inside RTL sentences.
- Repeat on a phone, where most visitors will be.
Treat right-to-left as a first-class layout from day one: document-level direction, logical CSS, deliberate mirroring rules, proper Arabic-script fonts, and one URL per language. Retrofitting RTL later costs far more than building it in.
Frequently asked questions
Set dir="rtl" and the correct lang attribute on the html element for the RTL version, build layouts with CSS logical properties instead of left and right, mirror directional icons and components, and test every page in both directions.
Yes. Separate URLs, such as /en/ and /ur/, let search engines index both languages, and hreflang annotations tell them which version to show to which searcher.
Urdu is traditionally set in the Nastaliq style, and Noto Nastaliq Urdu is a widely used free web font. Nastaliq needs a larger size and more line height than Latin text to stay readable.
Yes. Tailwind includes logical spacing and positioning utilities such as ms-, me-, ps-, pe-, start-, and end-, plus rtl: and ltr: variants for styles that must differ by direction.
Working on something like this?
See how our Website Development practice works, or talk to us directly. No pitch.



