Arabic localization testing for product teams

Learn how to test Arabic localization across strings, plurals, direction, layouts, formats, forms, metadata and release workflows.

Guide14 min read

A completed Arabic translation file does not mean the product is localized. The file may never supply strings for an empty state, a server error or an accessible name. A perfectly translated message may be assembled in the wrong word order. The interface may truncate it, move a Latin user name to the wrong place inside it or format its price for a different market.

Arabic localization testing follows the translated content through the running product. It asks whether every string reaches the correct state, whether variables and plural branches survive formatting, whether the document and components inherit the right direction, and whether the result remains usable at real viewport sizes.

That work belongs to several roles. An Arabic reviewer must judge language and market fit. Engineers and QA can verify much of the pipeline, layout and browser behavior without reading Arabic. Product managers decide the locale contract when several valid conventions exist. A good plan makes those boundaries explicit instead of sending every defect to "translation."

Define what the Arabic locale promises#

Start with a product decision, not a language file. Record the locale or locales in scope, the target markets and the conventions the release intends to use.

The contract should answer:

  • Is the product shipping generic Arabic, a market-specific locale such as ar-SA or ar-AE, or several variants?
  • Which digit system, calendar, date order, currency and time zone apply in each market?
  • Can user-generated content be Arabic, English or mixed?
  • Which names must remain untranslated, such as trademarks, legal entities, plan names or model codes?
  • What happens when an Arabic translation is missing: block the build, show a controlled fallback or omit the feature?
  • Which browsers, viewport sizes and assistive technologies are release targets?
  • Who approves linguistic quality, layout, formats and final release risk?

Do not let the locale identifier silently answer business questions it cannot settle. Runtime locale data has defaults, but the product may require a different numbering system or calendar. Likewise, "Arabic" does not say whether a brand name should be translated or transliterated.

Turn the contract into fixtures that exercise the translation layer: every message that takes a variable, filled once with an Arabic value and once with a Latin one; counts of 0, 1, 2, 3, 11 and 100, which land in each of the six plural categories Arabic has; a user name in each script; a date whose day is above 12; an amount with decimals; and an address from each supported market. Generic placeholder text will not exercise the real risks.

Test the string pipeline, not only the catalog#

A catalog comparison can prove that keys exist. It cannot prove that users will see the intended Arabic string. The application may request the wrong namespace, construct a key dynamically, load a stale bundle, fall back to English or bypass the localization layer for text returned by an API.

Map strings by source and runtime owner:

SourceTypical failuresHow to expose them
Client catalogMissing key, stale bundle, wrong namespaceVisit the state and inspect the resolved message
Server responseUntranslated error or statusTrigger each response path with the Arabic locale
CMSMissing Arabic entry, outdated revisionCompare published locale variants
Third-party widgetLocale not passed or unsupportedOpen the widget in the Arabic journey
Email or document serviceEnglish template or wrong formatGenerate the actual output from an Arabic account
Component defaultHard-coded placeholder, tooltip or labelRender empty and error states in isolation

Test state coverage rather than page coverage. For a search flow, that means initial, loading, results, no results, invalid query, network failure and retry. For checkout, include stock changes, invalid promotion codes, payment errors, confirmation and receipt. R011 reports untranslated interactive labels such as buttons, navigation links, menu items and tabs. R010 reports broader visible Latin-script text above its thresholds.

Attributes form a second translation surface. Inspect placeholder, alt, title, aria-label and button value content. These strings can come from component props that never enter the main catalog. R012 reports untranslated text in those attributes.

Do not flag every Latin token. Email addresses, URLs, product models and approved brand names may be intentional. Keep exceptions at the string or term level. Excluding an entire card or navigation region because it contains one approved English name can hide future fallbacks in the same component.

Build a missing-translation mode for test environments if the localization stack supports it. A visible sentinel around fallback strings makes gaps easier to distinguish from approved foreign terms. The sentinel must stay out of production and should not be the only test, because a key can resolve to an obsolete or contextually wrong Arabic translation.

Preserve whole messages and their variables#

Localization breaks when English sentence structure leaks into code. Concatenating fragments forces Arabic to reuse the source language's word order and makes grammatical agreement hard or impossible.

Fragile

js
const message = t("cart.prefix") + count + t("cart.items") + userName;

Better

js
const message = t("cart.summary", { count, userName });

The complete sentence belongs in one translatable message so the translator can place the variables where Arabic requires them. Variable names should describe meaning, such as deliveryDate or itemCount, rather than implementation positions such as value1.

Give translators the context the UI already knows. A short source string like "Open" can be a verb, an adjective or a status. "Order" can be a command or a purchase record. Include a screenshot, component name, character constraint when one genuinely exists, and a note describing each placeholder. Do not ask the translator to infer those facts from a key such as common.open.

Test variables with content that changes direction and width. Use an Arabic name, a Latin name, a long name, a numeric ID and a value containing punctuation. Confirm that the variable appears once, remains selectable and copyable, and is not escaped as visible markup. Where the variable has a different text direction from its sentence, isolate it in markup instead of embedding invisible controls in the translated message when markup is available.

Avoid giving translators HTML fragments unless the localization system explicitly supports safe rich-text placeholders. Raw markup increases the chance of broken tags, unsafe interpolation and reordered fragments that the component cannot render. Prefer structured placeholders whose boundaries remain under application control.

Exercise every Arabic plural branch#

An English-only test with one and many does not cover Arabic plural behavior. Unicode CLDR defines locale-specific plural categories based on how the surrounding phrase must change with a numeric value. The category names are technical labels, not direct grammatical instructions. The CLDR plural rules should drive selection, while an Arabic language reviewer supplies the actual phrasing.

Use the localization framework's plural support rather than conditional code copied from English:

js
const category = new Intl.PluralRules("ar").select(itemCount);

Intl.PluralRules returns the locale's category for a value. A message system such as ICU MessageFormat can keep the category choices inside one translatable message. ICU's message-format guidance recommends plural arguments for locale-aware selection instead of older generic choice patterns.

Do not hard-code a small list of magic values as the product's plural algorithm. Ask the runtime which category applies, then create fixtures that hit every category it reports for the supported locale. Include integers around boundaries, zero, two, teens, values above 100 and decimals if the product displays them. 1 and 1.0 can also deserve separate tests when the application preserves visible fraction digits.

There are two different assertions:

  1. Selection: The runtime chooses the expected message branch for the numeric input.
  2. Language: The translated branch is grammatically and contextually correct.

Engineering can automate the first. An Arabic reviewer owns the second. A test that merely confirms a non-empty string for each category catches missing branches but cannot approve the sentence.

Check the complete rendered message, not only the noun next to the number. Arabic agreement can affect other words. Also test the natural zero state. A dedicated phrase may be clearer than showing a numeric zero, even when the framework can route both through a plural category.

Make language and direction independent decisions#

Language and base direction are separate document properties, and a locale switch has to set both. The HTML dir documentation notes that language does not imply direction and recommends setting the root direction explicitly for RTL documents, so keep the direction next to each locale in configuration instead of expecting the framework to work it out from the language code:

js
const LOCALES = {
  en: { lang: "en", dir: "ltr" },
  ar: { lang: "ar", dir: "rtl" },
};

Inspect the live root after direct entry, hydration and client-side locale switching. A visible Arabic route can retain lang="en", dir="ltr" or both from the initial document. R001 reports a missing or left-to-right root direction on an Arabic page. R002 reports a missing, non-Arabic or contradictory root language. A global direction: rtl in CSS is no substitute for the attribute: components styled with :dir(rtl) never match it, as RTL testing: the complete guide shows.

Mark intentional language changes within the page:

html
<p dir="rtl">
  يتضمن الاشتراك <span lang="en" dir="ltr">Cloud Backup Pro</span>
</p>

The inner lang supports correct language processing. The inner dir establishes the product name's text direction. R080 reports intentional foreign-language runs with no language attribute. Do not add lang="en" to every number or email address, since those values are not English prose.

Isolate mixed-direction values#

Translated messages carry variables, and a variable written in the other direction can move the words around it. The browser lays out the line with the Unicode Bidirectional Algorithm, which gives digits and most punctuation no direction of their own.

Problem

html
<p dir="rtl">أضافت Sarah 3 تعليقات</p>

The translation is right: "Sarah added 3 comments". Measured in Chromium 151, though, the count displays between the verb and the name, away from the word it counts. The 3 follows a Latin name, so the algorithm joins it to the name's left-to-right run.

Better

html
<p dir="rtl">أضافت <bdi>Sarah</bdi> 3 تعليقات</p>

<bdi> isolates the name and takes its direction from the name itself, so the count stays beside its word. An Arabic name in the same slot displays correctly with or without the wrapper, which is why the bug only appears for some users. Put the isolation in the component that renders the variable: a translator cannot know which values will be Latin. The W3C inline bidi guidance explains the value of isolating an opposite-direction phrase from surrounding text.

Test every variable with an Arabic value, a Latin value, a number and trailing punctuation, at the start, middle and end of the message. Repeat after asynchronous content loads. R021 reports unisolated phones, emails and Latin tokens inside Arabic text, and R024 reports punctuation at the wrong visual end.

Do not "fix" the order by rewriting the translation around one test value. A message reordered to look right for Sarah looks wrong for an Arabic name, and copy and paste follows the source either way. Fix the markup boundary.

Test layouts with localized content, not mirrored English#

Switching an English fixture to RTL is useful for exposing physical CSS, but it is not a localization test. Arabic changes text width, line breaks, font metrics and the set of states that contain copy.

Use CSS logical properties for direction-relative layout:

Problem

css
.notice-icon {
  margin-right: 8px;
}

.notice {
  padding-left: 16px;
  text-align: left;
}

Better

css
.notice-icon {
  margin-inline-end: 8px;
}

.notice {
  padding-inline-start: 16px;
  text-align: start;
}

The CSS logical-properties guide describes how inline start and end map with writing direction. Physical properties remain valid when the requirement is genuinely physical, such as a venue's seat map, which shows where the stage really is.

Audit offsets, floats, corners, shadows, text indents and translateX. R030, R031, R032 and R033 report common direction-sensitive physical rules without an RTL counterpart. Avoid using row-reverse to simulate RTL; the container direction already changes a flex row's main-axis start, while visual reordering can fight the DOM and tab sequence. R081 reports that pattern.

At each supported breakpoint, load the longest approved Arabic strings, increase text size or zoom, wait for fonts and data, then open menus, filters, dialogs, tooltips, toasts and error summaries. Compare element bounding boxes with their containers and check both horizontal scroll extremes. Hiding overflow on the page is not a repair if content remains outside the viewport.

R040 reports document-level horizontal overflow. R041, R042 and R043 cover overlapping text, clipped text and fixed-pixel-width containers exceeded by Arabic content.

Icons carry meaning that never passes through a translator. The send arrow in a translated message composer points along the reading direction and usually needs its mirrored counterpart; a brand logo or a check mark does not. R025 reports a physically named directional icon that is never mirrored. Review the action and label, not only the glyph.

Verify Arabic typography and font loading#

Arabic is a connected script. Positive letter spacing inherited from an uppercase Latin label can separate letters and damage the word shape. text-transform: uppercase has no equivalent typographic role for Arabic. R051 reports positive letter spacing on Arabic text, and R055 reports uppercase and tracking styles applied to Arabic.

Inspect the rendered font once the translations are in. A declared family can cover Latin but omit Arabic, so the Arabic characters, and only those, fall through to a fallback face with a different width, baseline and line height, sometimes after the web font finishes loading. R050 reports measured fallback or a declared stack with no Arabic-capable family.

Test headings, body copy, numbers and mixed-language labels after fonts are ready. Look for disconnected or clipped letters, missing marks, uneven baselines and unexpected line wrapping. Use a stack that intentionally supports Arabic rather than accepting whichever system fallback happens to be present.

Line height and fixed component height need review together. A control may look generous with a Latin font but clip Arabic marks or a second line of validation text. R052 and R053 cover cramped line height and undersized Arabic body text. R054 reports italic or oblique Arabic styling so the team can decide whether the chosen typeface and design justify it.

Treat formats as localized content#

Dates, prices, percentages and units are part of the message, not post-processing decoration. The Arabic locale alone may not encode the product's full market decision.

The calendar is a good example. Current locale data gives ar-SA the Gregorian calendar and Arabic-Indic digits by default, and that data changes between runtime versions. A Saudi product that shows due dates in the Hijri calendar has to ask for it by name:

js
const dueDate = new Intl.DateTimeFormat("ar-SA", {
  calendar: "islamic-umalqura",
  numberingSystem: "latn",
  dateStyle: "long",
});

Whether dates appear in the Hijri calendar, the Gregorian calendar or both is a product and market decision that product and language owners approve. The formatter only carries it out.

Test a date with a day above 12, month names, midnight, a time-zone boundary, zero, decimals, thousands, negative amounts and percentages. Check the same value in cards, tables, filters, exports, emails and receipts. Different surfaces often call different formatters.

Do not rebuild a date from pieces, such as a translated month name pasted beside a formatted day: the formatter orders the parts for the locale and may add direction marks that a hand-built string drops.

R060 reports English month or day names and US-ordered dates in Arabic text. R061, R062, R063 and R064 cover mixed digit systems, foreign currency formatting in Saudi or UAE contexts, inconsistent percent or unit order, and Latin punctuation where an Arabic form belongs.

Test forms as editing experiences#

An Arabic form is not uniformly RTL at the field level, and an address form shows why. The street and district are Arabic prose and inherit right to left. A postal code is a single run of digits, which displays as written in either direction, so it needs no dir of its own:

html
<form lang="ar" dir="rtl">
  <label for="street">الشارع</label>
  <input id="street" name="street" autocomplete="address-line1">

  <label for="postal-code">الرمز البريدي</label>
  <input id="postal-code" name="postal-code" inputmode="numeric" autocomplete="postal-code">
</form>

Values with separators are different: email addresses, URLs and numbers written in groups need dir="ltr" on their fields, and only type="tel" is left to right by default. Test the computed direction and then edit a real value: type, paste, select, move the caret and delete around punctuation. R070 reports telephone, email and URL inputs rendered RTL, while R023 reports text inputs rendered LTR where Arabic input is expected.

Trigger required, format, server and cross-field errors. Native validation bubbles come from the browser, not from the page, so the root lang does not make them Arabic. If Arabic validation is a requirement, provide localized application messages and test their association with the field. R071 reports untranslated labels, validation and help text.

Check autocomplete tokens on identity and address fields, then test actual autofill in supported browsers. R073 reports identity fields missing those tokens. For selects, inspect both the closed value and expanded options in the target environments; R072 reports a left-to-right select containing Arabic options.

Split testing by expertise#

Teams do not need to wait for an Arabic speaker before finding every defect. They do need to reserve language decisions for someone qualified to make them.

Test areaCan be checked without reading Arabic?Final owner
Missing keys and fallback sentinelsYesEngineering or QA
Root lang and dirYesEngineering
Overflow, overlap and clippingYesQA and frontend
Bidi behavior of known valuesYes, with defined expected orderFrontend and QA
Plural branch coverageYesEngineering
Plural grammarNoArabic language reviewer
Translation accuracy and toneNoArabic language reviewer
Currency, calendar and digit policyPartlyProduct plus market expert
Field direction and keyboard orderYesQA and accessibility reviewer
Cultural or legal suitabilityNoRelevant market owner

The handoff between these roles needs evidence. A useful localization bug contains the route, locale, browser, viewport, application state, source key when known, actual string, expected behavior and a screenshot or minimal reproduction. For bidi defects, include the authored value separately from how it displayed. For plural defects, include the numeric input and selected branch.

Do not ask the language reviewer to compensate for engineering failures. Translators should not shorten accurate copy until it fits a fixed-width button, insert spaces to repair bidi layout, or rewrite a message because the application concatenates it from fragments. Fix the owning layer first.

Build localization into the release path#

Automate stable invariants in continuous integration:

  • required Arabic catalogs exist and contain no missing production keys;
  • placeholder names match across source and target messages;
  • every runtime plural category has a message branch;
  • Arabic routes render the expected root language and direction;
  • critical states contain translated accessible names and labels;
  • known field types have the intended direction;
  • selected pages have no unexpected horizontal overflow at target widths;
  • number and date formatters resolve the product's required options.

Add visual regression fixtures for high-risk components in initial, loading, empty, invalid and success states. Capture more than one width and wait for fonts. A single desktop snapshot of a happy path will miss most localization layout failures.

Keep linguistic review in the release path for new or changed copy. Review in context, not only in a spreadsheet. The reviewer needs to see variable values, nearby labels, control purpose, truncation and the task that follows the message.

A Ritla scan covers the rendered side of this pipeline: every check runs against the page as users get it, including untranslated labels (R011) and attribute text (R012) that a catalog comparison cannot see. Use each finding to open the exact state, confirm the defect, repair its owning layer and add a deterministic regression test where possible. The RTL testing checklist for Arabic websites provides a shorter pass for release day.

A release is ready when the catalog, runtime, layout and language review agree. Translation completion alone is only the first of those signals.

Checks in this guide

Show every check in this guideShow fewer

See what your Arabic pages are hiding

Paste a URL. Ritla renders the page on desktop and mobile, runs every check, and shows the top issues with screenshot evidence.