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 rightlanganddir="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
LeftandRightarrow 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 asmenu.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.txtand/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}| Key | What it does |
|---|---|
languageName | The name shown in the language switch |
languageCode | The address prefix (/ar/) and the file suffix (ar.json, menu.ar.json) |
contentDir | The folder name inside each content folder |
dir | rtl or ltr. This one value sets the direction of the page |
ogLocale | The language code for social previews, such as ar_SA or fr_FR |
dateLocale | The format for dates, such as ar or fr-FR |
weight | The 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.
-
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 rtlIt adds the language to
language.json, and copies your default language’s content folders, menu file, andsrc/i18n/file for you to translate. Files that already exist are kept unless you add--force. -
Translate the new content, menu, and interface labels. Add the language to Markdown links, such as
/he/privacy-policy/. -
If you host on Netlify, copy the
/ar/*block innetlify.tomlfor/he/*. The script doesn’t add it. -
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 insrc/styles/rtl.cssuse:lang(ar), so add the same rules for your language if it needs them. -
Restart
npm run dev, open/he/, and check the menu, a form, a project, and a journal post. Then runnpm run astro-check.
Remove Arabic
To turn Arabic off and keep the files, add it to disableLanguages:
[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 of | Use |
|---|---|
ml-*, mr-* | ms-*, me-* |
pl-*, pr-* | ps-*, pe-* |
left-*, right-* | start-*, end-* |
text-left, text-right | text-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 CSS | margin-inline-start |
padding-right in CSS | padding-inline-end |
left: 0 in CSS | inset-inline-start: 0 |
text-align: left in CSS | text-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,
rtlFlipIconsinsrc/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 addletter-spacingortext-transform, because they break Arabic script.
Do It With AI
Add [LANGUAGE] as a right-to-left language to my Margo site. Runnpm 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 frontmatterfield. 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.