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

Internationalization

Files: src/config/language.json, src/config/config.toml, src/i18n/, src/config/menu.<language>.json, src/content/**/<language>/ · Skill level: Beginner

Margo ships in English (the default, at /), French (at /fr/), and Arabic (at /ar/), with right-to-left support on Arabic pages. Every page, menu, and interface label exists in each language. You can keep all three, keep only your default language, or add another one. For how right-to-left works, see RTL & Arabic.

What Makes Up A Language

PartFiles
The language itselfan entry in src/config/language.json
Page and section texta folder per language in every content folder, such as src/content/sections/french/ and src/content/projects/arabic/
Interface textsrc/i18n/<language>.json, such as fr.json: buttons, labels, form messages, search texts, the footer copyright line
Menussrc/config/menu.<language>.json, such as menu.ar.json

This is src/config/language.json as it ships:

[
{
"languageName": "En",
"languageCode": "en",
"contentDir": "english",
"dir": "ltr",
"ogLocale": "en_US",
"dateLocale": "en-US",
"weight": 1
},
{
"languageName": "Fr",
"languageCode": "fr",
"contentDir": "french",
"dir": "ltr",
"ogLocale": "fr_FR",
"dateLocale": "fr-FR",
"weight": 2
},
{
"languageName": "العربية",
"languageCode": "ar",
"contentDir": "arabic",
"dir": "rtl",
"ogLocale": "ar_SA",
"dateLocale": "ar",
"weight": 3
}
]
KeyWhat it does
languageNameThe label in the header language switch
languageCodeThe address prefix (/fr/) and the file suffix (fr.json, menu.fr.json)
contentDirThe folder name inside each content folder
dirltr or rtl. This one value sets the direction of the page
ogLocaleThe language of social previews
dateLocaleThe format of dates
weightThe order of the languages

Visitors switch language with the language switch in the header and the language links in the footer. Each link goes to the same page in the other language.

Language Settings

src/config/config.toml
[settings.multilingual]
enable = true
defaultLanguage = "en"
disableLanguages = [""] # e.g. ["fr"] to switch French off without deleting it
showDefaultLangInUrl = false # true: English at /en/ instead of /

Restart npm run dev after you change these values.

Translate Or Edit Text

  • Page and section text: edit the file with the same name in the language’s folder, for example src/content/sections/french/hero-section.md. Keep the keys and structure the same as in English; translate the values only.
  • Interface text: edit the same key in the language’s file, for example nav.letsTalk (“Let’s talk”) in src/i18n/fr.json. Add a new key to every file in src/i18n/.
  • Menus: each src/config/menu.<language>.json keeps the same items, in the same order, with the same url values as menu.en.json. Translate the names. See Menus.
  • Links inside text: a Markdown link in a translated file carries its language prefix, such as [politique de confidentialité](/fr/privacy-policy/). Menu and button URLs don’t need it: the theme adds the prefix.
  • Prices and figures: prices such as a service’s price.from are written as text in each language file ("€9,200" in English, "9 200 €" in French). Change them in every language.

Tagline And Description Per Language

The site title, tagline, and description are set once in [site] of config.toml. Each language file can replace the tagline and description with its own text, in the site block at the top of src/i18n/<language>.json:

"site": {
"tagline": "Thème portfolio créatif pour Astro et Tailwind CSS",
"description": "Thème portfolio éditorial pour designers, studios et photographes, conçu avec Astro et Tailwind CSS."
}

An empty value uses [site] tagline or [site] description from config.toml. English ships with both empty, so it uses config.toml; French and Arabic ship with their own. Replace them when you write your own tagline. See SEO & AI Visibility.

Dates

Dates on journal posts follow dateLocale of the page language, with the Gregorian calendar and Western digits in every language, Arabic included.

Remove A Language

To turn one language off, add its code to disableLanguages in [settings.multilingual], for example ["fr"]. Its files stay in the project, and you can turn it back on later. Restart npm run dev.

To keep only your default language:

  1. Save a git commit or a copy of the folder, because the next steps delete files.
  2. Set enable = false in [settings.multilingual] of src/config/config.toml.
  3. Run npm run dev (or npm run astro-check) once. The script in the next step reads the settings file these commands write.
  4. Run npm run remove-multilingual. It deletes the content folders, the menu file, and the src/i18n/ file of every language except defaultLanguage, French and Arabic included, and rewrites language.json to list only the default language.

Add A Language

Example: German, code de, folder german.

  1. Run the language script:

    Terminal window
    npm run generate-multilingual-content -- --lang de --name Deutsch --dir-name german --locale de-DE --og de_DE
    OptionWhat it sets
    --langThe language code, required
    --namelanguageName
    --dir-namecontentDir, the folder name
    --localedateLocale
    --ogogLocale
    --dir rtlA right-to-left language. Leave it out for left to right
    --forceOverwrite files that already exist. Leave it out to keep your translations

    The script adds the language to the end of language.json, then copies your default language’s content folders, menu file, and src/i18n/ file. Files that already exist are kept unless you add --force.

  2. Translate the copies. In the copied files, add the language to Markdown links, such as [Datenschutz](/de/privacy-policy/).

  3. On Netlify, add a /de/* block to netlify.toml, copied from the /fr/* block. The script doesn’t write it.

  4. If the language’s alphabet needs its own font, add one to src/config/fonts.json, using the Arabic font as your model. See RTL & Arabic.

  5. Restart the dev server, open /de/, and run npm run astro-check.

Do It With AI

Add [LANGUAGE] (code [CODE], folder [FOLDER]) to my Margo site. Run
npm run generate-multilingual-content -- --lang [CODE] --name [NAME] --dir-name [FOLDER] --locale [LOCALE] --og [OG_LOCALE],
then translate the new content folders, src/config/menu.[CODE].json, and src/i18n/[CODE].json.
Keep every key and frontmatter field. Add the language prefix to Markdown links in the new files.
Add a /[CODE]/* block to netlify.toml copied from the /fr/* block. Then run npm run astro-check.
Translate my changes to every other language: for every file I changed in src/content/**/english/
today, update the file with the same name in each other language folder (same keys, translated
values), and add any new key from src/i18n/en.json to the other files in src/i18n/.
Then run npm run astro-check.
Type something to search...