Arabic RTL in websites and apps: what to get right

Youssef MohamedUpdated 14 min read

RTL is more than flipping the text

Arabic is read from right to left, and an Arabic interface has to follow the reader's eye. The whole layout starts on the right: the logo, the menu, the order of steps, the way a progress bar fills and the way you swipe through cards. Right-aligned paragraphs are only the part you notice first.

I build websites and Flutter apps for clients in Egypt, the Gulf and Europe, and most need both Arabic and English. Some are Arabic first, such as the Athenas food export site, the Midex engineering site, which also runs in English and German, and Khair Sanad, an Arabic platform for Islamic knowledge. On the app side there is Online Ezzay, an Arabic-first delivery app, and 90Plus, a football app in Arabic and English.

This guide is for business owners and developers alike: what to check, and how to build it.

What mirrors in an Arabic layout

When the interface switches to Arabic, everything that follows the reading order swaps sides:

  • The header: the logo on the right, menu items running right to left
  • Side menus and drawers, which open from the right edge
  • Columns, cards and table columns, with the first one on the right
  • Checkout and sign-up steps, with step one on the right
  • Progress and loading bars, which fill from right to left
  • Sliders such as a price range, with the minimum on the right
  • Tabs, with the first tab on the right
  • Carousels and swipes: the next card sits on the left, so you swipe the other way
  • Back and next buttons, breadcrumbs and pagination
  • Text alignment, list bullets and form labels

Icons and images with a direction

An icon mirrors when it points in the direction of reading or of time moving forward. A back arrow points right in Arabic, a next chevron points left, and a chat send icon usually points left too. Icons with lines of text, such as a document or a list, also mirror.

Icons of real objects stay as they are: a camera, a phone, a lock, a bell. Photos are never flipped, because any writing in them turns backwards. If an illustration shows someone walking toward the next step, ask the designer for a mirrored version.

Material icons in Flutter mirror the common arrows on their own. For a custom icon set, I mark each icon in the design file as mirror or keep.

What must stay as it is

  • Logos, and brand or product names written in Latin letters
  • Numbers: 2026 never becomes 6202, even inside Arabic text
  • Phone numbers, emails, URLs, order numbers and codes
  • Media controls such as play, fast-forward and rewind, and usually the video timeline
  • Clocks, maps and photos
  • Code snippets and keyboard shortcuts

Charts need a decision. A time axis running right to left matches the Arabic page; one running left to right matches the stock and currency charts many readers know. Neither is wrong. Pick one and use it in every chart.

Do not over-correct: a flipped logo or a backwards play button looks as broken as a menu that never mirrored.

Mixed Arabic and English in one line

Arabic sentences often contain English: a brand, a model number, an email, a price with a currency code. The Unicode bidirectional algorithm that browsers and phones use to order mixed text mostly works, but fails around punctuation, numbers and symbols with no direction of their own.

Typical symptoms: a phone number such as +20 100 000 0000 shows its groups reversed with the plus at the wrong end, and Smart Watch S2 (Black) loses its closing bracket to the other side.

The fix is to isolate the part with its own direction. On the web, wrap a number or English phrase in a span with dir="ltr". For text you do not control, such as a customer name from the database, use the bdi element. Give input fields and comment boxes dir="auto", so text follows the first letter typed.

In Flutter, give the Text widget its own textDirection, or wrap the number in the isolate characters U+2066 and U+2069. SMS, push notifications and WhatsApp templates have no HTML, so use the isolate characters or reword the sentence so the number comes last, and test on a real phone.

Arabic typography and font licences

  • More line height than Latin: I start body text around 1.7 and adjust per font
  • A slightly larger size, as many Arabic fonts look smaller than Latin at the same size
  • No letter-spacing, which breaks the joins between Arabic letters
  • No all-caps or italics: Arabic has no capitals and most Arabic fonts have no italic, so emphasize with weight, size or color
  • No justified text in the browser: it widens word gaps instead of stretching letters
  • Room for dots and diacritics, which tight line heights and fixed-height boxes can clip
  • Real regular, medium and bold weights, so the browser does not fake bold

Use one font family that covers both scripts, or a matched pair. Free options on Google Fonts include Noto Sans Arabic, IBM Plex Sans Arabic, Cairo, Tajawal and Almarai, all under the Open Font License.

Read a commercial font's licence before the design is approved. Web, app and print use are often licensed separately, some web licences count page views, and some forbid converting or publicly hosting the files. A font inside a Flutter app needs a licence that covers apps.

Western or Arabic-Indic digits

Arabic text can use Western digits (0123456789) or Arabic-Indic digits (٠١٢٣٤٥٦٧٨٩), and both are correct. Arabic-Indic digits are common in print and on signs in Egypt and parts of the Gulf; many Arabic websites and apps use Western digits.

Pick one style and use it everywhere: prices, dates, quantities, steps and charts. I default to Western digits, which are simpler for phone numbers and codes people copy, unless the client prefers otherwise.

Store numbers as numbers and format them only for display. Intl.NumberFormat defaults vary by country and browser version: in current data, ar-EG gives Arabic-Indic digits and ar-AE Western ones. Add -u-nu-latn or -u-nu-arab to the locale to force your choice; in Flutter, NumberFormat from the intl package does the same job.

Dates, Hijri and currency

Month names differ by region: Egypt and the Gulf mostly say يناير for January, while the Levant and Iraq say كانون الثاني. Format dates with the right locale rather than building strings by hand.

Hijri dates matter in Saudi Arabia and anything religious. Saudi Arabia's official Hijri calendar is Umm al-Qura, which browsers support as islamic-umalqura. Set the calendar explicitly with -u-ca-gregory or -u-ca-islamic-umalqura instead of trusting a default. The official start of Ramadan can differ from a calculated date by a day, so do not build promises on calculated dates.

For currency, choose symbol or code and keep the price together as one unit in mixed text. Arabic usually puts the amount first, as in 250 ج.م, with ر.س for the riyal and د.إ for the dirham; English pages often use EGP, SAR or AED. Saudi Arabia's new riyal symbol from 2025 has its own Unicode character, but many fonts lack it, so test it first.

Forms, input fields and search

  • Labels, helper text and error messages aligned to the start
  • Email, password, website and phone fields set to left to right, even on Arabic pages
  • Name, address and message fields set to automatic direction
  • Phone fields that accept +20, +966 or +971 and do not force one format
  • Arabic-Indic digits converted to Western digits before validating or saving
  • Validation messages in Arabic, not English text passed through from the server
  • Labels that stay visible, since placeholders disappear when someone types
  • Date pickers that follow the locale's first day of the week: Saturday in Egypt, Sunday in Saudi Arabia and Monday in the UAE in current data

The Arabic keyboard catches many forms: a phone number looks fine, then the server rejects it because the digits are not 0 to 9. Convert U+0660 to U+0669 and the Persian U+06F0 to U+06F9 on both client and server.

Search in an online store needs the same care. People type أحمد or احمد, mix up ة and ه, and swap ي and ى. Normalize these letters and ignore diacritics and tatweel before matching, or customers will miss products you actually sell.

On the web: dir, lang and CSS logical properties

Start with the html element. lang="ar" tells browsers, screen readers and translation tools that the page is Arabic, and dir="rtl" sets the direction. Flexbox and grid then follow it, so rows start on the right without extra CSS.

Then write CSS with start and end instead of left and right. Logical properties such as margin-inline-start, padding-inline, border-inline-start, inset-inline-end and text-align: start resolve to the right in Arabic and the left in English, so one stylesheet serves both. Tailwind has ms-4, pe-6 and text-start.

Some things do not flip by themselves: translateX(), background-position, box-shadow offsets, gradients written with to right, and JavaScript that reads scroll position or left offsets. Turn on the RTL option in carousel and date picker libraries. Never flip the whole page with a transform or row-reverse; keyboard focus and screen readers then move in the wrong order.

<!doctype html>
<html lang="ar" dir="rtl">
<head>
  <meta charset="utf-8">
  <style>
    .card {
      position: relative;
      padding-block: 1rem;
      padding-inline: 1.5rem;
      border-inline-start: 4px solid #0f766e; /* right in Arabic, left in English */
      text-align: start;
    }
    .card .icon {
      margin-inline-end: 0.75rem; /* space between the icon and the text */
    }
    .card .badge {
      position: absolute;
      inset-block-start: 0.5rem;
      inset-inline-end: 0.5rem; /* top left in Arabic, top right in English */
    }
    [dir="rtl"] .icon-next {
      transform: scaleX(-1); /* only for arrows that show direction */
    }
  </style>
</head>
<body>
  <p>اتصل بنا على <span dir="ltr">+20 100 000 0000</span></p>
  <p>المنتج: <bdi>Smart Watch S2 (Black)</bdi></p>
  <input type="email" name="email" dir="ltr" autocomplete="email">
  <textarea name="message" dir="auto"></textarea>
</body>
</html>

In apps: Flutter Directionality, start and end

Flutter supports right to left out of the box. With Arabic in supportedLocales and the global localization delegates, MaterialApp sets a right-to-left Directionality for the whole app, and Row, AppBar, Drawer and horizontal lists start from the right.

Avoid anything pinned to left or right: EdgeInsetsDirectional instead of EdgeInsets.only(left: ...), AlignmentDirectional instead of Alignment.centerLeft, PositionedDirectional instead of Positioned, and TextAlign.start instead of TextAlign.left. Read Directionality.of(context) when a custom painter or animation needs the direction.

PageView, Dismissible and the Cupertino page transition follow the direction too, but gestures you write yourself do not, so test custom swipes in Arabic. My separate Flutter articles on this blog cover translation files and Arabic plurals.

@override
Widget build(BuildContext context) {
  // Right to left whenever the app runs in Arabic.
  final isRtl = Directionality.of(context) == TextDirection.rtl;

  return Padding(
    padding: const EdgeInsetsDirectional.only(start: 16, end: 8),
    child: Row(
      children: [
        const Icon(Icons.phone),
        const SizedBox(width: 8),
        // The number keeps its left-to-right order inside an Arabic row.
        Text(phone, textDirection: TextDirection.ltr),
        const Spacer(),
        // A custom drawing needs the direction passed in.
        CustomPaint(
          size: const Size(48, 8),
          painter: StepPainter(isRtl: isRtl),
        ),
        // Material arrows such as arrow_forward mirror on their own.
        const Icon(Icons.arrow_forward),
      ],
    ),
  );
}

Write Arabic for Arabic readers

A perfectly mirrored layout still feels foreign if the words were translated line by line. Write Arabic copy for Arabic readers: shorter sentences, the words people actually use, and natural buttons such as اطلب الآن or تواصل معنا.

Decide the register early. Simple Modern Standard Arabic works across Egypt and the Gulf for most business sites; light Egyptian dialect can suit a consumer brand in Egypt. Words differ too: an app is usually تطبيق موبايل in Egypt and تطبيق جوال in Saudi Arabia.

Grammar shapes the interface. Verbs change with gender, so سجّل addresses a man, while the noun التسجيل stays neutral. Arabic has six plural categories in the Unicode rules (zero, one, two, few, many, other), so counts need real plural messages. And never build sentences from pieces; each message should be one full string with placeholders.

Machine translation is fine for a first draft, but someone fluent should rewrite it on the real screens, where an Arabic word may wrap or overflow.

SEO for a bilingual site

Give each language its own URL, such as /ar/ and /en/. A toggle that swaps the text on the same address with JavaScript or a cookie means Google sees one version only.

Connect the versions with hreflang links on every page, pointing to the page itself and to its other-language version, both ways. Each version's canonical points to itself, never to the other language. Translate the title, meta description, headings and alt text too.

Google detects language from visible content, not the lang attribute, but lang still matters for browsers and screen readers. Do not auto-redirect by location or browser language; offer a switch that leads to the same page in the other language.

Research Arabic keywords separately. People search phrases such as تصميم مواقع or برمجة تطبيقات, rarely a direct translation of your English keyword, and wording differs between Egypt and the Gulf. List both versions in your sitemap and check indexing in Google Search Console.

<!-- In the head of https://example.com/ar/services -->
<link rel="canonical" href="https://example.com/ar/services">
<link rel="alternate" hreflang="ar" href="https://example.com/ar/services">
<link rel="alternate" hreflang="en" href="https://example.com/en/services">
<link rel="alternate" hreflang="x-default" href="https://example.com/en/services">

<!-- The English page lists the same three alternates,
     with its canonical pointing to /en/services -->

Test both directions

I test every screen in both languages as it is built, not at the end:

  • Every screen in both languages, including empty, error and loading states
  • Real Arabic content of realistic length, not placeholder text
  • Mixed content: English names, emails, phone numbers and prices inside Arabic sentences
  • Keyboard tab order through every form
  • VoiceOver on iPhone and TalkBack on Android, in Arabic
  • A real phone set to Arabic, including notifications and the keyboard
  • Emails, PDF invoices, SMS, the admin panel, and third-party chat, maps and payment pages
  • In Flutter, widget or golden tests that wrap key screens in Directionality with TextDirection.rtl

Common mistakes and how to avoid them

  • Flipping the page with a transform or row-reverse instead of using dir and logical properties
  • Hard-coded left and right in CSS or Flutter
  • Mirrored logos, photos, play buttons and phone numbers
  • Missing lang and dir on the html element
  • Arabic clipped by tight line heights or fixed-height boxes
  • English error messages inside the Arabic interface
  • PDF invoices and emails with disconnected or reversed Arabic letters
  • Arabic added at the end, so every screen has to be opened again

Most come from treating Arabic as a translation job at the end. Built into the design system from the first screen, it costs little extra.

An existing site full of left and right can usually be fixed screen by screen. Ask for an audit first, then a quote based on its findings.

A launch checklist and what to do next

  • lang and dir are set, or Arabic is in the app's supported locales
  • Layout, navigation, steps, sliders and progress bars mirror
  • Logos, photos, media controls and numbers do not
  • Directional icons point the right way
  • Mixed text is isolated where needed
  • Line height, size and weights are tuned, with no letter-spacing
  • The font licence covers both web and app
  • One digit style, with dates and prices formatted
  • Forms accept Arabic-Indic digits and show errors in Arabic
  • Each language has its own URL, hreflang, canonical, title and description
  • Every screen is tested in both directions on real devices

Planning a new website, online store or app? Tell your developer on day one that Arabic is in scope, even if it launches later. It shapes the layout, font, URLs and budget.

If your Arabic version is weak, start with the screens that bring in money: home, product or service pages, sign-up and checkout. Run them through this checklist and fix what fails. If you want me to look at yours, send the link and the screens that matter most, and I will tell you what needs fixing and how much work it is.

Common questions

How do I make my website support Arabic RTL?
Set lang="ar" and dir="rtl" on the html element of your Arabic pages, and write CSS with logical properties such as margin-inline-start instead of left and right. Then check icons, mixed text, fonts and forms on every page. Built this way, one layout serves both languages.
Should an Arabic website use Arabic-Indic or Western numbers?
Both are correct; choose one and use it everywhere. Western digits are easier for phone numbers and codes people copy, while Arabic-Indic digits feel closer to traditional print. Either way, accept both in input fields and convert them before saving.
Do icons need to be flipped in an RTL design?
Only icons that show direction, such as back and next arrows, the send icon and progress indicators. Icons of real objects, logos and video playback controls stay as they are.
Should the Arabic version be on a separate domain or in an /ar/ folder?
Both work for Google as long as each language has its own URLs and the versions are linked with hreflang. A folder such as /ar/ is simpler to run and keeps everything in one site, so it is what I usually recommend. Separate country domains suit companies that run a different business in each country.
Can I use Google Translate for the Arabic version of my website?
Only as a first draft. Published as it is, it reads as translated, often gets gender and plural forms wrong and misses the words your customers search for. Have a fluent writer rewrite it on the real screens.
How much does Arabic add to the cost of a website or app?
It depends on the number of screens, who writes the Arabic, the font licence and how many third-party pieces need Arabic support, such as payments, emails and invoices. Planning it from the start costs far less than adding it later. Share your screens or scope and ask for a quote that lists Arabic as its own item.
Does Flutter support Arabic and right-to-left layouts?
Yes. With Arabic in supportedLocales and the global localization delegates, Flutter lays out the whole app right to left and mirrors Material arrows on its own. You still need directional padding and alignment, care with mixed text, and a test of every screen in Arabic.

Share

Available for new projects

Profiles