Skip to content
Type something to search...
Kivo Theme Documentation

Internationalization

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

Kivo ships in English (the default, at /) and French (at /fr/). Every page, menu, and label exists in both. Right-to-left languages such as Arabic or Hebrew are not supported.

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/blog/french/, …
Interface textsrc/i18n/fr.json (buttons, form messages, labels)
Menussrc/config/menu.fr.json

In src/config/language.json:

[
{ "languageName": "En", "languageCode": "en", "contentDir": "english", "weight": 1 },
{ "languageName": "Fr", "languageCode": "fr", "contentDir": "french", "weight": 2 }
]

languageName is shown in the language switch, languageCode is the URL prefix and the file suffix (fr.json, menu.fr.json), and contentDir is the folder name inside each content folder.

Language Settings

src/config/config.toml
[settings.multilingual]
enable = true
defaultLanguage = "en"
disableLanguages = [""] # for example ["fr"]
showDefaultLangInUrl = false # true gives /en/pricing/ instead of /pricing/

Restart npm run dev after any change here.

Use English Only

You have two options:

  • Turn French off, keep the files. Set enable = false (or disableLanguages = ["fr"]). Only English is built and the language switch disappears. You can turn French back on any time.

  • Delete French for good. First set enable = false and run npm run dev or npm run astro-check once, so .astro/config.generated.json exists (the script reads your default language from it). Then save a checkpoint (a git commit or a copy of the folder) and run:

    Terminal window
    npm run remove-multilingual

    It deletes every french/ content folder, src/i18n/fr.json, and src/config/menu.fr.json, and removes French from language.json. This can’t be undone without your checkpoint.

Replace French With Another Language

The easiest way to get a Spanish (or German, or Japanese) site is to turn the French copy into it:

  1. In language.json, change the French entry to "languageName": "Es", "languageCode": "es", "contentDir": "spanish".

  2. Rename every src/content/**/french/ folder to spanish/.

  3. Rename src/i18n/fr.json to es.json and src/config/menu.fr.json to menu.es.json.

  4. Translate the text values in those files and folders. Keep every key as it is, and change internal links in Markdown text from /fr/ to /es/.

  5. In netlify.toml, change the /fr/* redirect to /es/* and /es/404/.

  6. Restart npm run dev and open /es/.

Translating a whole site is a perfect job for an AI assistant: see the prompt at the end of this page.

Add A Third Language

Follow the same pattern without removing French:

  1. Add an entry to language.json, for example { "languageName": "De", "languageCode": "de", "contentDir": "german", "weight": 3 }.

  2. Copy src/i18n/en.json to de.json and src/config/menu.en.json to menu.de.json, then translate them.

  3. In every content folder that has an english/ folder, create a german/ copy and translate it.

  4. On Netlify, add a redirect block for /de/* to netlify.toml, like the French one.

  5. Restart npm run dev and open /de/.

These are the same steps as the “Add or remove a language” recipe in SKILLS.md, so an AI assistant can follow them for you.

  • Directorysrc/content/
    • Directorysections/
      • Directoryenglish/
        • …
      • Directoryfrench/
        • …
      • Directorygerman/
        • …
    • Directoryblog/
      • Directoryenglish/
        • …
      • Directoryfrench/
        • …
      • Directorygerman/
        • …
  • In menus and in url fields of buttons and links in content files, write the English path (/pricing/). Kivo adds the language prefix for you.
  • In Markdown text (the body of a post or page), write the full path for that language yourself: [see pricing](/fr/pricing/) in a French file.
  • If you use customSlug, give it the same value in every language so the language switch finds the matching page.

Translated 404 Pages

Each language has its own 404 page (/fr/404/). On Netlify, the redirect in netlify.toml sends a missing /fr/... address to it; add one block per extra language. Other hosts show the default (English) 404 page for every language.

Do It With AI

Replace French with [LANGUAGE] (code "[xx]", folder "[name]"). Update src/config/language.json,
rename every src/content/**/french/ folder to [name]/, rename src/i18n/fr.json and
src/config/menu.fr.json to [xx].json and menu.[xx].json, and update the "/fr/*" redirect in
netlify.toml. Then translate every text value in those files from the English versions. Keep all
keys, option values, icon names, URLs, and code samples unchanged. In Markdown text, change
internal links from /fr/ to /[xx]/. Work folder by folder and tell me when each is done.