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.*.json, src/content/**/<language>/ · Skill level: Beginner

Homio ships in English (the default, at /) and French (at /fr/). Every page, menu, label, price, and date exists in both. You can keep both, keep English only, or add another language.

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: src/content/sections/french/, src/content/services/french/, …
Interface textsrc/i18n/fr.json: buttons, labels, form messages, units, the booking steps, the 404 link labels
Menussrc/config/menu.fr.json
[
{
"languageName": "En",
"languageCode": "en",
"contentDir": "english",
"weight": 1,
"ogLocale": "en_US"
},
{
"languageName": "Fr",
"languageCode": "fr",
"contentDir": "french",
"weight": 2,
"ogLocale": "fr_FR"
}
]

languageCode is the URL prefix and the file suffix (fr.json, menu.fr.json), contentDir the folder name inside each content folder, languageName the label on the language links, weight their order, and ogLocale the language of social previews.

Visitors switch language with the EN | FR links in the footer and at the bottom of the phone menu. A link goes to the same page in the other language.

Your business details stay in one place for every language: [business] in config.toml (name, phone, address, hours). Don’t type them into translations.

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 french/ 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 src/i18n/fr.json, for example navigation.buttonLabel (“Get a price”).
  • Menus: src/config/menu.fr.json must keep the same structure as menu.en.json: the same items, in the same order, with the same url and source. Translate the labels.
  • Prices: keep every number in src/content/pricing/french/-index.md identical to the English file. npm run build prints a [pricing] warning listing any key that differs.

Check Your Translations

Terminal window
npm run check-i18n

It also runs as part of npm run astro-check, and fails when:

  • a key in src/i18n/en.json is missing from another language file, or the reverse,
  • a key in en.json is no longer read by any code,
  • a menu file differs from menu.en.json in structure (item count, url, source),
  • a content file in an english/ folder has no copy in another language folder, or the reverse.

It warns about empty strings and strings still equal to the English ones. Words that are the same in every language on purpose are listed in scripts/check-i18n.mjs.

Numbers, Prices, And Dates

Homio formats every price, number, date, and opening time for the page language with the browser’s Intl tools: $1,240 in English becomes 1 240 $US in French. You never write a formatted price in content: prices come from the numbers in the pricing file.

[settings.estimator]
currency = "USD" # ISO 4217 code, one currency for every language
currencyDisplay = "symbol" # symbol ($ / $US) | narrowSymbol ($ in every language) | code (USD)

Set currency to your own ("EUR", "GBP", "CAD"), and use narrowSymbol to show $ in French too. Opening hours and booking dates use timezone in [business].

Keep English Only

  1. Set enable = false in [settings.multilingual] of src/config/config.toml.
  2. Run npm run dev (or npm run astro-check) once.
  3. Run npm run remove-multilingual. It deletes every french/ folder, menu.fr.json, and fr.json, and rewrites language.json.

The script always keeps the English menu and interface strings. To keep only French or another language, remove the other files by hand instead.

Add A Language

Example: German, code de, folder german.

  1. Copy every english/ folder under src/content/ (each collection has one) to a german/ folder next to it.

  2. Add the language to src/config/language.json:

    {
    "languageName": "De",
    "languageCode": "de",
    "contentDir": "german",
    "weight": 3,
    "ogLocale": "de_DE"
    }
  3. Copy src/config/menu.en.json to src/config/menu.de.json, and src/i18n/en.json to src/i18n/de.json.

  4. Translate the copied content, menu, and interface strings.

  5. Run npm run check-i18n and fix what it lists.

  6. On Netlify, add a /de/* 404 block to netlify.toml, copied from the French one. Restart the dev server.

Right-to-left languages such as Arabic or Hebrew are not part of the theme.

Do It With AI

Add [LANGUAGE] (code [CODE], folder [FOLDER]) to my Homio site. Follow "Add or remove a language"
in SKILLS.md: copy every english/ content folder, add the entry to src/config/language.json, copy
menu.en.json and src/i18n/en.json, and translate them. Don't run generate-multilingual-content.
Keep every number in the pricing file identical. Then run npm run check-i18n and fix what it lists.
Translate my changes to French: for every file I changed in src/content/**/english/ today, update
the file with the same name in french/ (same keys, translated values, numbers unchanged), and add
any new key from src/i18n/en.json to fr.json. Then run npm run check-i18n.
Type something to search...