Languages
Publish every page in several languages, with proper URLs, hreflang, a language switcher and optional AI translation.
On this page
#Adding languages
Open Languages and add the languages you need. The default language lives at the root (/about); others get a prefix (/de/about). Prefer /en/about too? Turn on Prefix the default language. Changing languages or the default updates every URL, and the old addresses redirect.
#Translating a page
Open a page and use the language menu in the toolbar:
- Translate into Deutsch โ with the assistant set up, Claude translates the text and the new version opens as a draft for review. Only words are sent for translation; block structure, links, images and design tokens are copied unchanged.
- Add version / Copy for manual translation โ copies the page as a draft for someone to translate.
Each translation is linked to the original, so you can switch between versions, and pages are placed under the translated parent in a tree. The entries list has a language switch at the top.
A translation starts with its own place in search: it does not inherit a canonical URL or a noindex from the original. Give it its own slug and SEO title, written for that language: /de/preise, /fr/tarifs.
#URLs per language
Tree pages take their URL from their parents, so /de/vergleich/wordpress is a page wordpress under a German page vergleich. A collection with a fixed pattern can have another one per language with routes in its YAML:
route: /whats-new/{slug}
routes:
de: /neuigkeiten/{slug}
fr: /nouveautes/{slug}A language without a pattern of its own uses route, under its prefix. A collection's feed follows the same pattern.
#On the site
<html lang>anddirfollow the page (right-to-left languages included).- Each page lists its live translations as
hreflanglinks, with anx-default, also in the sitemap. - Links follow the visitor. A link to
/pricing, written in a block, a template, a menu or rich text, leads to/de/preiseon a German page once that version is live, and stays on the original until then. A link with anhreflangattribute means what it says and is left alone: use it on a language switcher. - Menus show the visitor's language where a translation is live, and each menu item can have its own label per language (Navigation).
- Forms have their wording per language, and answer in it (Forms).
- A missing page under
/de/shows the 404 template in German. - Text from the code (the skip link, a form's error messages) and dates (
entry.date|date) follow the page's language. /sitemap.xmlis an index of/sitemap-en.xml,/sitemap-de.xmland so on once more than one language has pages.- A Repeat over Languages makes a language switcher: bind a Link's label to
item.name(oritem.locale), its URL toitem.url, itshreflangandlangattributes toitem.locale, and thecurrentstate toitem.current. In PHP,cms_translations()returns the same list.
Languages without a live version of the page link to their home page instead, and are left out if that does not exist either.
#Templates and components
Templates and components exist once, so a design change reaches every language. The words in them come from a global set, which holds a value per language: switch language at the top of the set, and bind a block to it with globals.ui.sign_in. A value can be part of a sentence: {globals.ui.sold_by} {globals.company.display_name}.
#A page that stays in one language
To show content in the original language on purpose, publish a version with a short note in the reader's language and tick noindex. It stays out of hreflang and the sitemap, so search engines keep showing the original. This site's changelog works this way.