Internationalisierung (i18n)

Auf dieser Seite

Internationalisierung (i18n)

Übersetze deine Docs in andere Sprachen, jede mit ihrem eigenen URL-Präfix, ihrem eigenen <html lang dir> und einem automatischen Sprachumschalter - kein Plugin, kein separater Build-Schritt nötig.

Eine Locale hinzufügen

Übersetzte Inhalte liegen unter docs/i18n/<code>/, wobei sie deinen regulären docs/-Baum Seite für Seite spiegeln:

docs/
├── index.md
├── guides/
│   └── setup.md
└── i18n/
    ├── es/
    │   ├── index.md
    │   └── guides/
    │       └── setup.md
    └── ar/
        └── index.md

<code> wird sowohl zum Ordnernamen als auch zum gebauten URL-Präfix (docs/i18n/es/guides/setup.md/es/guides/setup/), halte ihn daher kurz - ein reiner Sprachcode (es, fr) oder ein Sprach-Region-Paar (pt-BR, zh-Hans) funktionieren beide, nur Buchstaben/Ziffern/Bindestriche. Dein regulärer docs/-Baum ist immer die Standard-Locale, unpräfixiert an der Wurzel der Website gebaut, genau wie heute - das Hinzufügen von docs/i18n/ ändert daran nichts.

Gib jeder Locale ein Anzeige-Label (und, für eine Rechts-nach-links-Sprache, ihre eigene Schreibrichtung) in bxsites.yaml:

i18n:
  defaultLocale: { code: en, label: English }
  locales:
    - { code: es, label: Español }
    - { code: ar, label: العربية, dir: rtl }
    - { code: pt-BR, label: "Português (Brasil)", flag: 🇧🇷 }
{
	"i18n": {
		"defaultLocale": { "code": "en", "label": "English" },
		"locales": [
			{ "code": "es", "label": "Español" },
			{ "code": "ar", "label": "العربية", "dir": "rtl" },
			{ "code": "pt-BR", "label": "Português (Brasil)", "flag": "🇧🇷" }
		]
	}
}

defaultLocale muss nur gesetzt werden, wenn deine Standard-Locale nicht Englisch ist; locales ist die Liste von allem anderen. Jeder docs/i18n/<code>/-Ordner wird automatisch gebaut, sobald er existiert - locales liefert nur sein Anzeige-Label und seine Textrichtung. Ein Ordner ohne passenden locales-Eintrag wird trotzdem gebaut (mit seinem reinen Code als eigenem Label), das ist also Metadaten, nicht das, was die Funktion ein- oder ausschaltet.

flag ist optional - der Umschalter wählt für rund 40 gängige Sprachcodes bereits von selbst ein sinnvolles Flaggen-Emoji (er prüft zuerst einen Regionscode wie pt-BR, dann fällt er auf die Basissprache pt zurück). Setze flag nur selbst, um diese Vermutung zu überschreiben, oder für einen Code, den die eingebaute Zuordnung nicht erkennt (in diesem Fall fällt sie auf ein schlichtes 🌐 zurück).

Was gebaut wird

Jede Locale ist ein echter, vollständig unabhängiger Build - eigene search-index.json, eigene assets/, alles, was ein normaler Build erzeugt - geschrieben unter site/<code>/ (site/es/, site/ar/). Nichts muss pro Locale aktiviert werden: sobald docs/i18n/es/ existiert, übernimmt bxSites build das von selbst.

Nicht übersetzte Seiten

Eine Locale muss nicht jede Seite übersetzt haben, um nutzbar zu sein. Eine Seite, die in docs/i18n/es/ fehlt, wird trotzdem unter ihrer erwarteten URL gebaut - sie zeigt den Inhalt der Standard-Locale, mit einem kleinen Hinweis oben auf der Seite, dass sie noch nicht übersetzt wurde. Nichts liefert einen 404, nichts sieht halbfertig aus, während eine Übersetzung noch in Arbeit ist.

Die Navigation jeder Locale hat immer genau dieselbe Form wie die der Standard-Locale - dieselben Seiten, dieselbe Reihenfolge, dieselbe Verschachtelung (was auch immer die eigene Ordnerstruktur von docs/, oder eine explizite nav, bereits erzeugt) - nur mit Titel/Inhalt jeder Seite, aus ihrer eigenen Übersetzung eingesetzt, wo eine existiert. Das ist auch das, was den Sprachumschalter funktionieren lässt: ein Sprachwechsel bringt dich auf dieselbe Seite, übersetzt oder nicht, niemals auf die Startseite dieser Locale.

Der Sprachumschalter

Sobald mehr als eine Locale existiert, rendert jedes Theme automatisch ein Sprach-Dropdown in der Kopfzeile - nichts, wozu man sich anmelden müsste, genau wie beim Versionsumschalter. Es zeigt die Flagge der aktuellen Locale als Auslöser; öffnest du es, listet es jede Locale mit ihrer eigenen Flagge und ihrem Label, die aktuelle als aktiv markiert. Wähle eine Locale, die du gerade nicht baust, und sie wird einfach gar nicht gerendert.

Versionierte und übersetzte Docs

Siehe Versionierung für docs/versions/<name>/ selbst. Versionen und Locales lassen sich auf einer Ebene kombinieren: lege einen docs/versions/<name>/i18n/<code>/-Ordner neben die eigenen Seiten einer Version, der die eigene Struktur dieser Version genau so spiegelt, wie ein oberstes docs/i18n/<code>/ docs/ selbst spiegelt:

docs/
  versions/
    2.0/
      index.md
      guides/
        setup.md
      i18n/
        es/
          index.md          # translated
          guides/
            setup.md        # untranslated pages still fall back, same as top-level i18n

Das baut site/versions/2.0/es/. Die eigenen Seiten der Standard-Locale einer Version (site/versions/2.0/) erhalten ebenfalls einen Sprachumschalter, der nur die Locales listet, für die diese Version selbst Übersetzungen hat - eine Version ohne eigenen i18n/-Unterordner wird genau so gerendert wie vorher, kein Umschalter gezeigt. Ein Versionswechsel fällt immer auf die eigene Standard-Locale dieser Version zurück (nimmt nie an, dass die Zielversion dieselbe Übersetzung hat); ein Locale-Wechsel bleibt immer auf der aktuellen Version.

Theme-Chrome (UI-Texte)

Der gesamte umgebende UI-Text jedes eingebauten Themes - der Suchplatzhalter, "Auf dieser Seite", "Diese Seite bearbeiten", "Zuletzt aktualisiert", die 404-Seite, der Titel der Tags-Seite und der Hinweis "noch nicht übersetzt" selbst - wird jetzt auch pro Locale übersetzt, nicht nur dein eigener Seiteninhalt.

Vier Locales bringen von Haus aus eine eingebaute Übersetzung mit: de, es, it und ja. Baust du einen dieser Locale-Codes, erhältst du automatisch vollständig übersetztes Theme-Chrome - nichts zu konfigurieren. Jeder andere Locale-Code (oder eine Seite, die du lieber anders formulieren möchtest) fällt auf Englisch zurück - überschreibe nur die Schlüssel, die dich interessieren, mit deinen eigenen strings im jeweiligen Locale-Eintrag in bxsites.yaml:

i18n:
  defaultLocale: { code: en, label: English }
  locales:
    - code: fr
      label: Français
      strings:
        searchPlaceholder: Rechercher dans la documentation...
        onThisPage: Sur cette page
    - code: es
      label: Español
      strings: { toggleDarkMode: Cambiar a modo nocturno }
{
	"i18n": {
		"defaultLocale": { "code": "en", "label": "English" },
		"locales": [
			{
				"code": "fr",
				"label": "Français",
				"strings": {
					"searchPlaceholder": "Rechercher dans la documentation...",
					"onThisPage": "Sur cette page"
				}
			},
			{
				"code": "es",
				"label": "Español",
				"strings": { "toggleDarkMode": "Cambiar a modo nocturno" }
			}
		]
	}
}

Eine Locale mit eingebauter Übersetzung (wie es oben) kann trotzdem einzelne Schlüssel genauso überschreiben - deine eigenen strings gewinnen immer sowohl gegen die eingebaute Übersetzung als auch gegen den englischen Standardwert. Auch defaultLocale selbst kann eigene strings tragen, für ein Projekt, dessen Standard-Locale nicht Englisch ist und das eigene Chrome-Formulierungen möchte, statt auf den englischen Standardwert zurückzufallen.

Die vollständige Liste überschreibbarer Schlüssel: searchPlaceholder, searchAriaLabel, searchNoResults, toggleDarkMode, toggleNavigation, toggleSection (Platzhalter {title}), repository, version, language (Platzhalter {label}), onThisPage, editThisPage, downloadMarkdown, lastUpdated, notTranslatedNotice (Platzhalter {locale}), notFoundTitle, notFoundBody, tagsTitle und pageNavigation.

Was (vorerst) außen vor bleibt

  • Blog-Chrome bleibt auf Englisch. Die eigenen UI-Texte des Blog-Subsystems ("Categories", "Archive", "Read more", "N min read", ...) werden vom strings-Override oben noch nicht erfasst - nur der Rest des Theme-Chromes ist es.
  • Der Datumswert von lastUpdated ist nicht locale-abhängig. Sein Label wird übersetzt; der Datums-/Uhrzeitwert selbst wird unabhängig von der Locale weiterhin gleich formatiert.
  • Die RTL-Layout-Spiegelung ist grundlegend, nicht pixelgenau. dir="rtl" wird korrekt gesetzt, und Sidebar/Kopfzeile spiegeln sich tatsächlich, aber ein paar dekorative Details (etwa die Seite des Akzentbalkens einer Admonition) drehen sich noch nicht mit.
  • Keine automatische Übersetzung. Jede Datei unter docs/i18n/<code>/ wird von Hand verfasst, genau wie jede andere Markdown-Seite - es gibt keinen maschinellen Übersetzungsschritt.

Eigene Icons und Includes

Ein custom:-Icon-Verweis und ein ::: include lösen beide gegen die eigenen docs/assets//wiederverwendbaren Inhalte deines Projekts auf, unabhängig davon, welche Locale gerade gebaut wird - das sind gemeinsam genutzte Assets, nichts, was ein Übersetzer pro Locale duplizieren müsste.

SEO

Die Seiten jeder Locale sind neben denen der Standard-Locale in sitemap.xml und llms.txt enthalten, genauso wie es versionierte Seiten sind.

Diese Seite bearbeiten Markdown herunterladen Zuletzt aktualisiert Aug 28, 2026, 3:16:38 AM