Skip to content
New: Customize your theme with an AI assistant. Read the guide

RTL & Arabic

Files: src/config/language.json, src/config/fonts.json, src/i18n/ar.json, src/config/menu.ar.json, src/content/**/arabic/, src/styles/rtl.css · Skill level: Beginner

Margo supports right-to-left (RTL) languages, and ships with Arabic as a complete example at /ar/. Every page, menu, and label has an Arabic version. For how languages work in general, see Internationalization.

What Changes In RTL

Direction comes from one setting, so there is nothing to switch on page by page. On a page in an RTL language:

  • <html> gets the right lang and dir="rtl", and the layout mirrors.
  • The header menu mirrors: flyouts open towards the left (and flip when there is no room), the shared panel slides in the direction you move, and the Left and Right arrow keys follow the reading direction. The phone menu card and the folding header items mirror too.
  • The menu names on Arabic pages come from src/config/menu.ar.json, which ships translated, with the same items and links as menu.en.json.
  • The arrow keys of the lightbox, tabs, and code tabs follow the reading direction.
  • Arrows and chevrons that point along the reading direction flip. The testimonial carousel’s arrows step the other way.
  • Code, email addresses, phone numbers, and the email, phone, and web address fields of forms stay left to right.
  • Arabic text uses an Arabic font, IBM Plex Sans Arabic, which loads only on Arabic pages. Latin text stays in the theme’s Latin fonts.
  • Arabic text keeps normal letter spacing and no capital-letter styles, and headings get a little more line height. The serif accent word in headings is set in the Arabic font, because the serif font has no Arabic letters.
  • Dates use the language’s format, with Western digits.
  • Arabic pages share the fallback social image, because the social card generator can’t lay out Arabic text (see SEO & AI Visibility).
  • The llms files and Markdown copies work at /ar/llms.txt and /ar/llms-full.txt.

The Language Entry

This is the Arabic entry in src/config/language.json:

{
"languageName": "العربية",
"languageCode": "ar",
"contentDir": "arabic",
"dir": "rtl",
"ogLocale": "ar_SA",
"dateLocale": "ar",
"weight": 3
}
KeyWhat it does
languageNameThe name shown in the language switch
languageCodeThe address prefix (/ar/) and the file suffix (ar.json, menu.ar.json)
contentDirThe folder name inside each content folder
dirrtl or ltr. This one value sets the direction of the page
ogLocaleThe language code for social previews, such as ar_SA or fr_FR
dateLocaleThe format for dates, such as ar or fr-FR
weightThe language’s position in the language switch

Every language has these keys. The theme reads them from this file, so you never list languages anywhere else.

The Arabic Font

The Arabic font is the third entry in src/config/fonts.json:

{
"name": "IBM Plex Sans Arabic",
"variants": [
{ "style": "normal", "weight": "400" },
{ "style": "normal", "weight": "500" },
{ "style": "normal", "weight": "600" }
],
"preload": false,
"display": "swap",
"cssVariable": "--font-arabic",
"provider": "google",
"subsets": ["arabic"],
"fallback": false,
"optimizedFallbacks": false,
"languages": ["ar"]
}

"languages": ["ar"] loads it only on Arabic pages. The Arabic text rules are in src/styles/rtl.css.

Add Another RTL Language

These steps add Hebrew. Any RTL language works the same way.

  1. Run the language script with --dir rtl:

    Terminal window
    npm run generate-multilingual-content -- --lang he --name עברית --dir-name hebrew --locale he-IL --og he_IL --dir rtl

    It adds the language to language.json, and copies your default language’s content folders, menu file, and src/i18n/ file for you to translate. Files that already exist are kept unless you add --force.

  2. Translate the new content, menu, and interface labels. Add the language to Markdown links, such as /he/privacy-policy/.

  3. If you host on Netlify, copy the /ar/* block in netlify.toml for /he/*. The script doesn’t add it.

  4. Add a font that covers the language to src/config/fonts.json, using the Arabic entry as your model, with "languages": ["he"]. The Arabic text rules in src/styles/rtl.css use :lang(ar), so add the same rules for your language if it needs them.

  5. Restart npm run dev, open /he/, and check the menu, a form, a project, and a journal post. Then run npm run astro-check.

Remove Arabic

To turn Arabic off and keep the files, add it to disableLanguages:

src/config/config.toml
[settings.multilingual]
disableLanguages = ["ar"]

Restart npm run dev. To delete the files instead, npm run remove-multilingual removes every language except your default one, French included. Save a git commit or a copy of the folder first, and read Internationalization before you run it.

If You Add Your Own Code

Use logical CSS, which follows the direction of the page, instead of left and right:

Instead ofUse
ml-*, mr-*ms-*, me-*
pl-*, pr-*ps-*, pe-*
left-*, right-*start-*, end-*
text-left, text-righttext-start, text-end
rounded-l-*, rounded-r-*rounded-s-*, rounded-e-*
border-l-*, border-r-*border-s-*, border-e-*
space-x-*gap-*
margin-left in CSSmargin-inline-start
padding-right in CSSpadding-inline-end
left: 0 in CSSinset-inline-start: 0
text-align: left in CSStext-align: start

translate-x-*, transform-origin, and gradient directions have no logical version, so handle them with the rtl: variant or [dir="rtl"].

Other rules:

  • Direction icons flip in one list, rtlFlipIcons in src/layouts/helpers/Icons.astro. Add new ones there, not where you use them, because icon names can come from content files.
  • Wrap values that must stay left to right with dir="ltr" or <bdi>, such as a code sample.
  • Under :lang(ar), don’t add letter-spacing or text-transform, because they break Arabic script.

Do It With AI

Add [LANGUAGE] as a right-to-left language to my Margo site. Run
npm run generate-multilingual-content -- --lang [CODE] --name [NAME] --dir-name [FOLDER] --locale [LOCALE] --og [OG_LOCALE] --dir rtl,
then translate the new content, menu, and interface label files. Keep every key and frontmatter
field. Add a font that covers the language to src/config/fonts.json with "languages": ["[CODE]"].
Add a /[CODE]/* block to netlify.toml. Use logical CSS only. Don't run remove-multilingual.
Then run npm run astro-check and list the pages I should check by eye.
Type something to search...