Languages
This documentation site is published in English. Configure additional locales when you have translated pages ready to publish.
Configure locales to serve translations from separate folders inside every documentation version:
import { defineConfig } from 'markupress';
export default defineConfig({
locales: {
en: { label: 'English' },
fr: { label: 'Français' },
ar: { label: 'العربية' },
},
defaultLocale: 'en',
});Put the default locale's landing page in docs/en/index.md, French in docs/fr/index.md, and Arabic in docs/ar/index.md. By default, every configured locale needs a landing page in every version. With localeFallback: 'source', only the default locale needs one. The default locale keeps URLs such as /guide/install/; other locales use /fr/guide/install/. Without locales, pages stay directly in docs/ and keep their existing URLs.
Locale IDs are BCP 47 language tags. Each locale has a label and optional directory, lang, and dir. The folder defaults to the locale ID, lang defaults to that ID, and dir accepts ltr, rtl, or auto. Without dir, native locale data supplies the reading direction; Arabic uses RTL. A page can override its content language and direction with lang and dir front matter. Locale folders must stay inside their version and must not overlap. If defaultLocale is omitted, the first configured locale is served without a language prefix.
Document identity
Translations share an id in front matter even when their file names differ:
---
id: installation
---If no id is set, identity is the page's route within its locale and version. The language menu lists actual translations of the current page in the selected version. Missing translations and source fallback copies are omitted. The menu appears when at least two translations are available. When viewing a fallback page with only its source available, the header links directly to that language. Direct visits to a missing translation use the configured fallback behavior.
A version switch stays in the selected language. Historical version URLs put the language first, for example /fr/v/1.2.3/guide/install/. The default version uses /fr/guide/install/. Snapshots copy all locale folders together (see Versions).
Untranslated content
Set localeFallback: 'source' to show the default locale's content when a translation is missing in the selected version:
export default defineConfig({
locales: { en: { label: 'English' }, fr: { label: 'Français' } },
defaultLocale: 'en',
localeFallback: 'source',
});A missing French page at /fr/reference/ shows its source article with a French notice. The article keeps its source language and direction. Navigation, code controls, dates and site branding use the selected locale. Set translations.untranslatedContent to customize the notice; {locale} is the selected language label.
Translations take precedence by document identity, even with a different filename. Links inside source content select translated identities where available and otherwise use source fallback in the same locale and version. Images, downloads and component imports resolve from the original file. Search includes fallback sections at their selected-locale URLs and respects each source page's search: false setting.
Fallback pages name their source page as canonical. The sitemap and alternate-language links include actual translations and owning source pages. A translated folder can begin empty or be absent, and adding, renaming or deleting translations updates fallback selection during development.
Omit localeFallback, or set it to 'home', to use the documentation-home behavior.
Navigation and search
Page titles, folder navigation, footer content, and Markdown links come from the selected locale's files. Put a separate _footer.md in each locale folder. Root-relative documentation links stay in the current language and version; asset links still resolve relative to their original source or the version's public folder.
Each language and version has its own local search index. An index at /fr/v/v1/_search.json contains the French v1 catalog, including source fallback when enabled; /fr/_search.json links the default version's French pages without its version prefix.
With multiple locales, the default layouts provide a Looma language menu with keyboard navigation and a check beside the current language. Without JavaScript, language links appear in a wrapping row in the footer. Replacement layouts receive a locales list with href, label, lang, current, and note, plus the existing version and navigation data. They also receive fallbackNotice, an empty string on translated pages or the translated source-content notice.
Reader interface
The default theme includes English, French and Arabic reader strings. Other languages use English until you provide overrides. The interface follows the configured locale language, independently of a page's lang front matter. Authored headings, page titles and navigation labels come from your content.
Set translations globally or on a locale. Locale overrides apply last; omitted keys inherit the built-in language. TranslationOverrides and Translations, exported from markupress, list the available keys:
import { defineConfig } from 'markupress';
export default defineConfig({
locales: {
en: { label: 'English' },
fr: {
label: 'Français',
title: 'Documentation du projet',
editLink: 'https://example.com/edit/main/',
translations: {
codeCopy: 'Copier le code',
searchResults: { one: '{count} résultat trouvé', other: '{count} résultats trouvés' },
},
},
},
});String placeholders are named: {count} in search counts, {query} in empty results, {version} and {locale} in unavailable-document notices, {label} in section overviews, and {notice} in notice dismissal. Values are inserted literally. Counts use native number formatting and the locale's plural category: zero, one, two, few, many or other.
A locale can also override title, nav, logo, favicon, titleTemplate, headerNotice, editLink and dateFormat. Omitted values inherit the site option. editLink: false disables that locale's generated edit links; page front matter can still specify its own.
Dates and direction
Last-updated dates keep an ISO datetime attribute and display in the interface language. They use Intl.DateTimeFormat with a long date and UTC by default, so a git calendar date does not shift with the server's time zone. Set dateFormat globally or per locale to supply native formatting options, for example { dateStyle: 'medium' }.
The layout follows the document direction. Code blocks stay left-to-right and isolated from surrounding text; inline code is isolated too. Explicit image placements wrap-left and wrap-right retain their physical meaning.
Replacement layouts receive the resolved ui dictionary, uiLang, and page.lastUpdatedText in addition to the language and version links. Keep the ISO page.lastUpdated for the <time datetime> value.
Language metadata
With origin configured, pages declare alternate-language links for available translations of the same document identity in the same version. The links use each counterpart's canonical URL and include x-default when that identity exists in the default locale. A missing translation has no alternate entry.
The default version uses its root URLs, including a deployment base; explicit version aliases keep that owning version's canonical group. Snapshots have separate source directories, so their alternate links stay within the snapshot. A page's head.canonical overrides its URL in the group. A source served through several independent owning routes has no automatic group; use native aliases for alternate URLs of one page.