International commerce

Shopify RTL Options Display

Arabic, Hebrew, and Persian markets read and type right-to-left, and the personalization option UX has to follow. Get RTL wrong and your storefront looks broken to 500M+ Arabic-speaking shoppers; get it right and you unlock a market most Shopify apps don't serve well. Here is the CSS logical-property approach, the mixed-script input handling, and the POD partner Arabic-font compatibility matrix.

Last updated: August 23, 2026~11 min readBy the Print It My Way team

What "RTL" actually breaks in a personalization storefront

RTL doesn't just flip the text direction — it flips the entire layout. In an Arabic storefront, the primary nav appears on the right, the sidebar collapses on the left, form labels sit to the right of inputs, and the cart drawer slides in from the left instead of the right. The personalization option selector needs the same treatment: dropdowns open toward the reading direction, character counters live at the input's start-edge (right, in RTL), and progress indicators fill right-to-left.

Set the direction at the root

Shopify's default themes ship with basic RTL support if you set the language direction correctly. In your theme's theme.liquid:

<html lang="{{ request.locale.iso_code }}" dir="{{ request.locale.iso_code | rtl_ltr }}">

<!-- Custom filter (Liquid snippet) -->
{% assign rtl_langs = "ar,he,fa,ur" | split: "," %}
{% if rtl_langs contains request.locale.iso_code %}
  {% assign dir = "rtl" %}
{% else %}
  {% assign dir = "ltr" %}
{% endif %}
<html lang="{{ request.locale.iso_code }}" dir="{{ dir }}">

Use CSS logical properties, not physical directions

Physical CSS (margin-left, padding-right) requires you to write a separate RTL stylesheet. Logical CSS (margin-inline-start, padding-inline-end) inverts automatically based on the document direction. Rewrite your personalization option CSS with logical properties and one stylesheet works for both directions:

/* WRONG — hard-coded direction */
.option-label { margin-left: 12px; padding-right: 8px; }

/* RIGHT — inverts automatically */
.option-label { margin-inline-start: 12px; padding-inline-end: 8px; }

/* Logical property mapping */
margin-left     → margin-inline-start
margin-right    → margin-inline-end
padding-left    → padding-inline-start
padding-right   → padding-inline-end
border-left     → border-inline-start
text-align: left → text-align: start
left / right    → inset-inline-start / inset-inline-end

Handle mixed-script input

Arabic-market customers frequently mix Arabic + Latin text — an Arabic name followed by an English company. Force a single direction and the mixed input looks scrambled. Use dir="auto" on text inputs so the browser detects direction per input:

<label for="engraving">نص التخصيص</label>
<input id="engraving" type="text" dir="auto"
       placeholder="Type your text — أدخل النص">

With dir="auto", if the first strong-directional character is Arabic, the cursor sits right and text flows RTL. If it's Latin, the cursor sits left. Both feel native.

POD partner Arabic font matrix

POD partnerArabic fontsHebrew fontsDiacritics (tashkeel)Kashida (justification)
PrintfulNoto Sans Arabic + 3 displayNoto Sans HebrewSupportedManual only
PrintifyNoto Sans ArabicNoto Sans HebrewSupportedNot supported
GelatoNoto + Tajawal + CairoNoto Sans Hebrew + Frank RuhlSupportedSupported
GootenNot supportedNot supported
CustomCatNot supportedNot supported
Diacritics matter. Arabic personalizations for religious contexts (Quranic phrases, names of God) often include vowel marks (tashkeel). If your POD partner strips diacritics silently, you'll get orders returned as "misspelled" when the customer's original input was correct. Gelato and Printful preserve them; Printify does for standard Arabic but occasionally loses them on decorative fonts. Test each font before enabling.

Live preview font swap

Your live preview canvas needs an Arabic-capable font. Load Noto Sans Arabic when the input contains Arabic characters:

const ARABIC_RANGE = /[؀-ۿݐ-ݿ]/;
const HEBREW_RANGE = /[֐-׿]/;

function fontFor(text) {
  if (ARABIC_RANGE.test(text)) return "'Noto Sans Arabic', sans-serif";
  if (HEBREW_RANGE.test(text)) return "'Noto Sans Hebrew', sans-serif";
  return "'Inter', sans-serif";
}

engravingInput.addEventListener('input', e => {
  previewCanvas.font = `48px ${fontFor(e.target.value)}`;
  previewCanvas.direction = 'inherit'; // uses dir=auto from input
  redrawPreview(e.target.value);
});

Character-count and validation

Arabic letters connect and take more physical width than Latin. A 20-character English name and a 20-character Arabic name are not the same physical length on a printed item. Set per-script character limits (Arabic 12-15, Hebrew 15-18, Latin 20). Also, Arabic combining marks (tashkeel) count as separate codepoints — normalize before counting so "مُحَمَّد" (with vowels) counts as 6 letters, not 10 codepoints.

Cart drawer + option review

The cart drawer that slides in from the right in LTR should slide from the left in RTL. Personalization option summaries in the cart line ("Text: John") need the label direction to follow the input direction — Arabic labels with Latin values in the middle of an RTL layout should use bidi isolation with <bdi> tags:

<li>النص: <bdi>{{ property_value }}</bdi></li>

Frequently asked questions

How do I enable RTL on Shopify for Arabic personalization?

Set dir="rtl" on the html element when the current locale is Arabic, Hebrew, Persian, or Urdu. Use CSS logical properties (margin-inline-start) instead of physical (margin-left) so one stylesheet works for both directions.

Does Shopify support Arabic personalization out of the box?

Partially — Shopify Markets + Translate & Adapt handle Arabic UI translation, but the option-input handling (mixed-script, dir=auto, character-count per script) requires an app that supports RTL. Print It My Way handles this natively.

What Arabic font should I use for personalization previews?

Noto Sans Arabic is the safest default — every major POD partner supports it, it's free via Google Fonts, and it renders diacritics correctly. Cairo and Tajawal are good display alternatives when supported by your POD partner.

How do I handle mixed Arabic + English input?

Use dir="auto" on the input element. The browser detects direction from the first strong-directional character and orients cursor + text flow accordingly. For displaying mixed input in an RTL layout (e.g., cart line), wrap the value in a <bdi> tag to isolate its direction from the surrounding text.

Which POD partners support Arabic personalization?

Printful, Printify, and Gelato all support Arabic (Noto Sans Arabic minimum). Gooten and CustomCat do not. Gelato has the most robust Arabic support including diacritics and kashida justification.

Do Arabic personalizations count characters differently?

Yes — Arabic letters connect and take more physical width than Latin. Set a lower character limit for Arabic (~12-15) than Latin (~20). Also normalize combining marks (tashkeel) so "مُحَمَّد" counts as 6 letters instead of 10 codepoints.

Best Shopify app for RTL personalization?

Print It My Way — supports dir=auto inputs, script-aware character limits, RTL cart drawers, and CSS logical-property styling that works across LTR and RTL themes.

How do I test my RTL personalization storefront?

Set your browser language to Arabic (chrome://settings/languages), visit your Arabic-market URL, and complete a full purchase with mixed Arabic + Latin text. Verify: cart drawer slides from left, character count respects Arabic width, POD partner receives the correct file with diacritics preserved.

Related reading

Try it free on Shopify

Print It My Way's permanent Free plan includes native RTL support, mixed-script input handling, and Arabic-capable preview rendering.

Install Print It My Way