Arabic website testing: the complete guide
Learn how to test Arabic websites for locale routing, translation, RTL behavior, layout, typography, formats, forms and accessibility.
Guide15 min read
An Arabic homepage can pass a design review while the product still fails in ordinary use. The language switcher may send users back to English at checkout. A contact number may show its digit groups in reverse order. A translated error may overflow only after submission. Search engines may receive an Arabic URL whose canonical points to the English page.
Those are different defects with different owners. Arabic website testing has to cover the locale as a system: routing and metadata, translation completeness, document semantics, bidirectional text, layout, typography, local formats, form behavior and interaction order. A mirrored screenshot proves almost none of that.
Run the test as a sequence of product tasks, not a tour of static pages. Create an account, search, filter, buy, correct an invalid form, open a receipt and return later through a saved Arabic URL. The expensive failures usually appear at the transitions between those states.
Define the Arabic test contract first#
Before opening a browser, write down what the Arabic release claims to support. At minimum, identify:
- the Arabic locale tags and markets in scope, such as generic Arabic, Saudi Arabia or the UAE;
- the URL pattern for each locale and whether a locale switch preserves the current page;
- the supported browsers, operating systems, viewport range and assistive technologies;
- the required numbering system, calendar, date order, currency and time-zone behavior;
- which content may remain in another language, such as trademarks, model numbers or legal names;
- whether user-generated content can be Arabic, English or either;
- the critical tasks that must work before release.
This prevents subjective bug reports later. A price rendered with Western digits is not automatically wrong for Arabic, and an English product name is not automatically untranslated. Both depend on the product's market and content rules. What is wrong is inconsistency without a defined reason.
Build fixtures from real content shapes. Include a long Arabic navigation label, a two-line validation error, the contact number with its country code, the support email address, branch codes, a promotion code, a large price, a date whose day is above 12, an empty search result and a customer name in each script. These values expose more than generic placeholder copy.
Keep the Arabic and source-language fixtures tied to the same application state. If the English screenshot shows a paid order and the Arabic screenshot shows an empty cart, the comparison cannot isolate locale behavior.
Test routing before visual details#
Start with entry, navigation and persistence. A perfect RTL page is not useful if users cannot reliably reach it or stay in it.
Open an Arabic URL directly in a new private session. Refresh it, follow an internal link, open a link in a new tab, sign in, sign out and trigger any server redirect used by the task. The locale should survive each transition according to the product contract. Repeat with a deep URL, not only the homepage.
Then switch languages while viewing a specific item. A useful switcher keeps the equivalent route and meaningful state when an equivalent exists. Sending every switch to the homepage discards the user's place. If there is no Arabic equivalent, define the fallback explicitly and make it visible rather than silently showing English under an Arabic URL.
Check the network and response, not just the address bar. The server-rendered document should contain the intended locale before client hydration where server rendering is part of the architecture. A page that initially delivers English metadata and swaps to Arabic in the client can produce a visible flash and inconsistent results for tools that do not execute the same client path.
For public sites, inspect the canonical and language alternates. Google recommends distinct URLs for language versions and documents how hreflang identifies localized variants. The Arabic page should include an Arabic alternate, and its canonical should represent the intended Arabic URL rather than collapsing it into a different-language page. R003 reports an Arabic page whose alternate set has no Arabic entry, while R006 reports a canonical pointing at a different-locale variant.
Do not combine language alternatives with the canonical relation as if they were interchangeable. Canonicalization selects a representative URL; hreflang relates localized alternatives. Google's canonical URL guidance treats them as separate annotations.
Verify document language, direction and metadata#
The live Arabic document should normally begin with this semantic baseline:
<html lang="ar" dir="rtl">lang identifies the content language. dir sets its base direction. One does not imply the other. Assistive technology uses language information for text processing and pronunciation, and the W3C accessibility guidance recommends declaring the page language and marking parts that change language.
Inspect the rendered html element after every locale change, including client-side navigation. A stale lang="en" can remain after the visible copy becomes Arabic. A stylesheet declaration such as direction: rtl may make the page look correct but does not replace semantic direction. In Chromium, :dir(rtl) does not match an element whose only direction comes from CSS. R001 reports a missing or left-to-right root direction on an Arabic page; R002 reports a missing, non-Arabic or contradictory root language.
The document title, meta description, social title and social description are separate translation surfaces. Open the raw response or DOM head and read each one. Also check the social locale value and the image's localized text if the product uses a text-bearing social image. R004 covers a title or meta description that remains mostly Latin on an Arabic page, and R005 covers untranslated social metadata or a missing or invalid social locale.
Use lang on intentional foreign-language phrases when they are meant to be read as another language:
<p dir="rtl">
اقرأ تقرير <cite lang="en" dir="ltr">Cloud Security Review</cite>
</p>The direction and language annotations solve different problems. The dir boundary controls bidi layout; lang identifies the language of the phrase. R080 reports intentional foreign-language runs with no language annotation.
Find translation gaps by state, not by page#
Translation coverage is often tested on the initial render and fails after interaction. The missing strings live in states that screenshots rarely include: loading, no results, validation, confirmation, permission denial, session timeout and destructive-action dialogs.
For each critical task, force these states where they exist:
| State | Examples to inspect |
|---|---|
| Initial | Navigation, headings, field labels, placeholders |
| Loading | Skeleton labels, progress text, accessible status messages |
| Empty | No-results copy, recovery action, illustration alternative text |
| Invalid | Inline error, error summary, field description, toast |
| Success | Confirmation message, receipt, follow-up action |
| Restricted | Permission message, disabled-control explanation |
| Expired | Session warning, sign-in action, preserved return URL |
| Offline or failed | Network error, retry action, support link |
Search for untranslated interactive text first. A paragraph left in English is visible, but an English button or menu item blocks a task more directly. R011 reports untranslated buttons, navigation and footer links, menu items and tabs. R010 covers broader visible Latin-script body text above its thresholds.
Text hidden in attributes needs a separate pass. Inspect placeholders, image alternatives, tooltips, aria-label values and button value attributes. Turn off images or use the accessibility tree to expose labels that are not visible in the default view. R012 reports these untranslated attribute strings.
Do not treat every Latin token as an error. Product names, email addresses, URLs and model codes can be intentional. Keep an allowlist narrow and based on content policy, not on selectors that exclude a whole component. A broad exception can hide a future English error message in the same region.
Test interpolation and plural branches with more than one value. A message may be translated for one item but fall back to English for zero or many. Also inspect text produced by the backend, third-party widgets and downloaded documents. They may use different translation catalogs from the web client.
Test bidirectional content with hostile values#
Arabic interfaces regularly contain left-to-right fragments. The browser resolves the combined line using the Unicode Bidirectional Algorithm, not by keeping every substring in source order. Arabic and Latin letters establish strong directional runs; numbers and punctuation interact with the surrounding context under different rules.
A contact number is a good reproduction case on a public site, because the same number appears in the header, the footer and the contact page:
Problem
<p dir="rtl">للتواصل: +971 4 123 4567</p>Measured in Chromium 151, the number displays as 4567 123 4 971+: after the Arabic label, its space-separated groups are laid out from right to left. Reversing the string in the template is not a fix. Copy and paste and screen readers follow the source, so they would get the reversed digits, and the number would read backwards anywhere it appears in left-to-right text.
Better
<p dir="rtl">للتواصل: <span dir="ltr">+971 4 123 4567</span></p>A phone number is always left to right, so dir="ltr" states that directly. For a value whose direction you cannot know in advance, such as a customer's display name, <bdi> or dir="auto" takes the direction from the value itself. The W3C inline bidi guidance explains why an opposite-direction phrase should be tightly wrapped rather than allowed to affect adjacent punctuation. Keep the wrapper around the number alone: a dir="auto" element that also holds the label takes its direction from the label's first Arabic letter.
Test the values a public site actually shows before declaring mixed content done:
- the contact number in the header, the footer and the contact page;
- a branch or store code, such as
DXB-04; - the support email address and a link to a tracking page;
- opening hours, prices and a promotion code;
- the same values at the beginning, middle and end of an Arabic sentence;
- punctuation immediately after the isolated span;
- values injected after the first render.
Values that start with Latin letters, like DXB-04, stay intact after Arabic text. Values that start with digits and are split by hyphens or spaces do not, and RTL testing: the complete guide explains why. R021 reports unisolated phones, emails and Latin tokens inside Arabic text. R024 reports punctuation at the wrong visual end of Arabic text.
Audit layout as relationships#
Do not compare Arabic and English screenshots pixel for pixel. Test relationships: inline-start navigation belongs at inline start, the field icon stays attached to its field, the primary action retains its hierarchy, and a genuinely physical object stays physical.
Physical CSS is the first place to look when a component works in English and drifts in Arabic.
Problem
.site-header {
display: flex;
}
.site-nav {
margin-left: auto;
}In the English header, margin-left: auto pushes the navigation away from the logo to the far edge. In the Arabic header the flex row starts at the right, so the same margin pushes the navigation back toward the logo, and both end up bunched at the right edge.
Better
.site-nav {
margin-inline-start: auto;
}CSS logical properties map start and end according to writing direction. They remove many locale-specific overrides. Physical properties remain appropriate when the requirement is physical, such as the pins on a store-locator map.
Review absolute offsets, margins, padding, borders, corner radii, floats, shadows, text indentation and horizontal transforms. A positive translateX always moves toward the physical right. Decide whether the motion was meant to be physical or directional. R030, R031, R032 and R033 report common physical assumptions without an RTL counterpart.
Do not add flex-direction: row-reverse merely to imitate RTL. A flex row in an RTL container already follows the direction of its main axis. Reversing it again can produce a visually convenient order that disagrees with the DOM and keyboard sequence. R081 reports that pattern.
Icons need semantic review. On a marketing site, start with the arrows on carousels, "read more" links and pagination, which point along the reading direction. Logos, check marks in a pricing table and the play button on a video keep their shape. Name the asset by action rather than by left or right, then test the label, icon, placement and click target as one control. R025 reports a physically named directional icon that is never mirrored.
Stress text, fonts and bounding boxes#
Arabic changes more than reading direction. Its connected script, glyph shapes, vertical marks and font metrics change the space a component needs.
Check the rendered font in DevTools on a page that mixes scripts, such as a product page with an English brand name inside an Arabic description. If the declared web font has no Arabic glyphs, the Arabic falls through the stack while the brand name keeps the intended face, and the mixture changes baselines, widths and line breaks. R050 reports measured fallback or a declared stack with no Arabic-capable family.
Remove Latin display treatments from Arabic text. Positive letter spacing can pull apart a connected script, and uppercase has no equivalent effect on Arabic letters. R051 reports positive letter spacing on Arabic text, while R055 reports uppercase and tracking styles carried over from Latin. Synthetic italics also deserve review rather than automatic inheritance; R054 reports italic or oblique Arabic text.
Test the longest realistic content at the minimum viewport and at 200 percent zoom. Open menus, dialogs, toasts, table filters and validation summaries. Wait for web fonts and API data before measuring. Compare each suspicious element's bounding rectangle with its container and the viewport.
An unexpected horizontal scrollbar is evidence, not the defect itself. Locate the element whose box escapes. overflow-x: hidden on the page only hides the route to the content and can make it unreachable. R040 reports document-level horizontal overflow. R041, R042 and R043 cover overlapping text, clipped content and fixed-width containers exceeded by Arabic text.
Body text needs enough size and line height for the chosen face and content. Check multi-line paragraphs and errors, not a Latin specimen in a design file. R052 and R053 report cramped line height and Arabic body text below the stated threshold.
Verify locale formats as product requirements#
The locale string alone is not a complete formatting specification. Runtime locale data determines defaults, and those defaults can change. By default, ar-SA and ar-EG format numbers with Arabic-Indic digits, while ar and ar-AE use Western digits, and all four use the Gregorian calendar. Those defaults come from locale data that changes between runtime versions, so a pricing page should not depend on them:
const planPrice = new Intl.NumberFormat("ar-AE", {
style: "currency",
currency: "AED",
numberingSystem: "latn",
});Intl.NumberFormat and the Intl.DateTimeFormat constructor both accept numberingSystem, and dates also take calendar. The example is one market decision, not a recommendation for every Arabic product.
Use test data that makes mistakes visible: a day above 12 for date order, an amount with thousands and decimals, a negative balance, zero, a percentage, midnight and a time close to a time-zone boundary. Check tables, cards, filters, exports and notifications. Formatting code often differs between them.
Do not strip invisible characters from formatted output before rendering. Locale formatters may include spacing or bidi controls that keep the result readable in context. Test the complete rendered string next to its Arabic label.
R060 reports English month or day names and US-ordered dates in Arabic text. R061 covers mixed Arabic-Indic and Western digits in one context, R062 covers foreign currency formatting in a Saudi or UAE market context, and R063 covers inconsistent percent or unit ordering.
Operate forms with Arabic and LTR values#
An Arabic form needs field-level direction decisions. On a public site the first forms most visitors meet are the search box and the newsletter signup, and they need opposite answers:
<form role="search" lang="ar" dir="rtl">
<label for="site-search">ابحث في الموقع</label>
<input id="site-search" name="q" type="search">
</form>
<form lang="ar" dir="rtl">
<label for="newsletter-email">البريد الإلكتروني</label>
<input id="newsletter-email" name="email" type="email" dir="ltr" autocomplete="email">
</form>The search field inherits right to left, which suits Arabic queries. The email field would inherit it too, which is why it sets dir="ltr": only type="tel" is left to right by default. Inspect the computed direction, then type, paste, select, delete and move the caret through a realistic value. A still screenshot cannot reveal editing behavior. R070 reports telephone, email and URL controls rendered RTL; R023 reports text inputs rendered LTR where Arabic input is expected.
Trigger every validation path. Check label, help text, inline error, summary, toast and focus movement. Submit the newsletter form empty: the bubble that appears comes from the browser, and the page's lang does not translate it, so a browser running in English shows it in English on this Arabic page. If Arabic validation is required, provide localized application messages rather than relying on browser UI. R071 reports untranslated form labels, validation and help text.
Test autofill on identity, address, email and phone fields. The HTML autocomplete attribute describes the data a field expects and supports tokens such as name, email, tel, street-address, shipping and billing. Do not remove it to work around an RTL styling issue. R073 reports identity fields missing autocomplete tokens.
For selects, check the closed value, expanded options, arrow, focus and keyboard behavior in the supported environments. Native rendering differs, so record the actual browser and operating system for failures. R072 reports a left-to-right select with Arabic options.
Test accessibility after visual mirroring#
Visual order can change while DOM order stays fixed. That is sometimes acceptable, but the keyboard path and reading sequence must preserve meaning and operation. The WCAG focus-order guidance does not demand pixel-order equivalence; it requires a logical sequence that works with the relationships communicated by the page.
Test without a pointer. Tab through the header and main task, use arrow keys inside menus, tabs and other composite widgets, submit invalid data, open and close a dialog, and confirm focus returns to the trigger. Focus must remain visible at every step. Watch for jumps caused by row-reverse, CSS order or positive tabindex values.
Inspect the accessibility tree for names and roles. A visually translated icon button can still expose an English aria-label. A decorative icon can become noisy if it gains a translated alternative instead of remaining hidden. Language changes within an Arabic page should be marked where they affect pronunciation.
Use a screen reader in at least one supported environment for the critical journey. Listen for page title, headings, landmarks, control names, error association, status announcements and the pronunciation of intentional foreign-language content. Automated accessibility rules can identify missing semantics, but they cannot decide whether the spoken task order makes sense.
Automate invariants and keep judgment manual#
Automate facts that should remain stable on every build:
- the Arabic route returns successfully and keeps its locale through redirects;
- the live root has the expected
langanddir; - the canonical and alternate annotations point to intended locale URLs;
- critical controls expose translated names and labels;
- known LTR fields and Arabic text fields have the expected direction;
- the document has no unexpected horizontal overflow at selected widths;
- focus follows the expected critical-task sequence;
- formatters return the required currency, calendar and numbering system;
- screenshots for high-value states stay within reviewed visual differences.
Keep human review for translation quality, whether a phrase is truly intentional, whether an icon's meaning reverses, whether mixed text is readable to an Arabic user, and whether the task still feels coherent. These are not weaker tests. They answer questions that a deterministic assertion cannot.
Avoid one enormous end-to-end test that reports only that the Arabic journey failed. Layer the suite. Component tests cover directional variants and overflow fixtures. Integration tests cover locale state, formatting and validation. Browser journeys cover routing, focus and dynamic surfaces. A targeted failure is much faster to diagnose.
A Ritla scan runs every check against the rendered pages it crawls, which suits the part of this pass that repeats across templates: document setup, untranslated labels, unisolated values, physical CSS and overflow. Treat each finding as a reproduction lead. Confirm it in the affected product state, fix the owning layer, and add a regression test where the behavior is deterministic. For a shorter release-day pass, use the RTL testing checklist for Arabic websites.
Run the final pass in risk order#
The order of a test pass affects what it finds. Start with failures that invalidate everything beneath them:
- Entry and locale persistence: Direct Arabic URLs, redirects, navigation, authentication and language switching.
- Document contract: Root language and direction, title, metadata, canonical and language alternatives.
- Critical task copy: Interactive labels, validation, empty states, confirmations and attribute text.
- Mixed-direction values: Phones, emails, IDs, percentages and dynamic content in Arabic sentences.
- Layout under pressure: Narrow widths, zoom, long text, loaded fonts, overlays and overflow.
- Formats and forms: Market-specific dates, numbers and currency, then real editing and autofill.
- Keyboard and assistive technology: Logical focus, visible focus, accessible names, errors and announcements.
- Regression evidence: Automated checks, reviewed screenshots and recorded browser-specific results.
When a failure appears, classify it before patching it. A reordered contact number is a bidi-boundary problem, not a flexbox problem. A clipped error is a sizing problem, not a reason to reduce the Arabic font. An English native validation bubble is not fixed by translating lang. Debugging the layer that owns the behavior produces a smaller change and a test that states what must stay true.
Checks in this guide
- R003hreflang alternate set lacks any Arabic entry on an Arabic page
- R006Canonical URL points at a different-locale variant
- R001document direction missing, contradicted, or declared only in CSS
- R002html[lang] missing, non-Arabic, or contradicting detected content
- R004<title> or meta description majority-Latin on an Arabic page
- R005OpenGraph/Twitter metadata untranslated or og:locale missing/invalid
Show every check in this guideShow fewer
- R080Intentional foreign-language runs missing a lang attribute
- R011Untranslated interactive labels (buttons, nav/footer links, menu items, tabs)
- R010Visible Latin-script body text above thresholds on an Arabic page
- R012Untranslated attribute text (placeholder, alt, title, aria-label, button value)
- R021Unisolated bidi hazards: phones, emails, Latin tokens inside Arabic text
- R024Punctuation rendering at the wrong visual end of Arabic text
- R030Direction-sensitive physical properties without an RTL override
- R031float: left/right on content elements in RTL context without override
- R032Direction-sensitive shadow x-offsets without an RTL counterpart
- R033translateX moves the element off-screen in RTL
- R081flex row-reverse faking RTL instead of dir (tab order fights visual order)
- R025Directional icon pointing against the sequence its control advances
- R050Arabic text falling back past the declared font family (measured, declared, or a webfont that failed to load)
- R051letter-spacing applied to Arabic text (breaks the connected script)
- R055Latin display styling (uppercase + tracking) applied to Arabic
- R054Italic/oblique applied to Arabic text
- R040Document-level horizontal overflow
- R041Visible text-bearing elements overlapping
- R042Clipped text: content wider than its box with overflow hidden and no ellipsis
- R043Fixed-pixel-width container whose Arabic text exceeds the space
- R052line-height below 1.5 on Arabic body text
- R053Arabic body text below 14px
- R060English month/day names or MM/DD/YYYY dates in Arabic text
- R061Arabic-Indic and Western digits mixed in the same context
- R062Foreign currency formatting in a SAR/AED market context
- R063Percent/unit ordering inconsistencies (%50 vs 50%)
- R070tel/email/url inputs rendered RTL (these must stay LTR)
- R023Text inputs rendered LTR where Arabic input is expected
- R071Untranslated form labels / validation / help text
- R073Identity fields missing autocomplete tokens
- R072<select> rendered LTR with Arabic options