The usual plan is: build it in English, add Arabic later. It sounds like a scheduling decision. It is actually an architecture decision, and by the time "later" arrives, several of its consequences are already baked in.
An Arabic audience notices immediately. The moment the layout reads left-to-right, the icons point the wrong way, and the copy has the cadence of a translation, the product feels imported — regardless of how correct the words are.
Direction is a layout property, not a text property
Right-to-left is not "flip the text". Everything positional flips with it: the back arrow, the progress bar, the sidebar, the label of a form field, the direction a card animates in from.
The practical version of this is boring and effective — use logical
properties instead of physical ones. margin-inline-start rather than
margin-left; border-inline-start rather than border-left. Written
that way, one stylesheet serves both directions and the layout mirrors
itself. Retrofitted afterwards, every physical left in the codebase
becomes a bug that only some of your users see.
The same applies to motion. A panel that slides in from the right is arriving from off-screen in English and from the content in Arabic. A horizontal scroll animation that travels negatively in one direction must travel positively in the other. These take minutes to get right up front and hours to chase later.
Matching text is harder than displaying it
Displaying Arabic is a font problem. Comparing Arabic is a normalisation problem, and it is where quietly unfair behaviour hides.
The same word is legitimately written several ways: with or without hamza (إجابة / اجابه), taa marbuta or haa at the end, alef maqsura or plain yaa, with or without diacritics, with or without tatweel stretching. A user who typed the right answer and got marked wrong will not file a bug report — they will just decide the product is broken.
In the party-game platform we built, this is handled by one shared normalisation spec that every game engine uses, rather than each feature inventing its own comparison. It is the same principle as putting rules in the database: one definition, referenced everywhere, instead of five implementations that drift.
Numerals, dates, and the things nobody lists
Arabic-Indic numerals (١٢٣) versus Western (123) is a per-context choice, not a global switch — prices and phone numbers often stay Western even in fully Arabic interfaces. Mixed-direction strings need care: a sentence in Arabic containing an English product name or a version number will render in a surprising order unless the bidirectional algorithm is given the right hints.
And Arabic type has different needs. Line height that looks generous in Latin can feel cramped once you have ascenders, descenders, and diacritics in the same line. Picking a family with a real Arabic face — rather than letting the system fall back to whatever it has — is the difference between "translated" and "designed".
The naming decision most teams skip
On the wedding-invitation platform we built, the brand itself differs by language: Vows in English, زفّة in Arabic. Not a transliteration of the English name — a name chosen in Arabic, for Arabic speakers.
That is the clearest signal of the whole approach. Transliterating a name produces something that is pronounceable but means nothing. Choosing a name in each language means each audience gets a brand that landed in their own language first.
What it actually costs
Designed together from the start, bilingual support is a modest surcharge: logical properties instead of physical ones, one normalisation spec, a second font face, and design reviews that look at both directions before build. Retrofitted, it is a rewrite of the layout layer plus a long tail of "only in Arabic" bugs.
The order is the whole cost difference. Everything else is the same work.