Zum Inhalt springen
Blume
Esc
↑↓navigieren↵öffnen⌘Jvorschau
Auf dieser Seite

Internationalisierung

Stelle deine Dokumentation in mehreren Sprachen bereit – mit locale-bewusstem Routing, sprachspezifischer Navigation, übersetzter Benutzeroberfläche und SEO – alles konventionsbasiert.

Blume stellt ein Projekt in vielen Sprachen bereit. Lege übersetzte Dateien an der richtigen Stelle ab, und Blume verdrahtet Routing, den Sprachumschalter, die Navigation pro Locale und SEO für dich – es gibt keine separate Routing-Ebene zu pflegen. Es ist optional: Ohne einen i18n-Block bleibt deine Website genau wie zuvor einsprachig. Es lässt sich außerdem mit Versionierung kombinieren – ein eingefrorener Snapshot behält seine Übersetzungen, und der Locale-Fallback funktioniert innerhalb jeder Version.

Aktivieren

Füge einen i18n-Block hinzu, der deine Locales auflistet und angibt, welche die Standard-Locale ist:

i18n: {
  defaultLocale: "en",
  locales: [
    { code: "en", label: "English" },
    { code: "fr", label: "Français" },
    { code: "ar", label: "العربية", dir: "rtl" },
  ],
}

Jede Locale hat einen code (wird in URLs verwendet), ein label (wird im Sprachumschalter angezeigt) und ein optionales dir für Rechts-nach-links-Schriften (standardmäßig "ltr"). Ein optionales style gibt blume translate freie Hinweise für die Locale – Register, Dialekt, Terminologie, z. B. "Brazilian Portuguese, informal você" – sodass die Wahl von der allerersten Übersetzung an festgelegt ist, statt vom Agenten entschieden zu werden.

Übersetzte Inhalte organisieren

Die Standard-Locale liegt im Stammverzeichnis deiner Inhalte. Jede weitere Locale ist ein Ordner der obersten Ebene, benannt nach ihrem code, der die Standardstruktur spiegelt:

docs/
  index.mdx               ->  /
  guides/quickstart.mdx   ->  /guides/quickstart
  fr/
    index.mdx             ->  /fr
    guides/quickstart.mdx ->  /fr/guides/quickstart
  ar/
    index.mdx             ->  /ar
Datei Route
docs/index.mdx /
docs/guides/quickstart.mdx /guides/quickstart
docs/fr/guides/quickstart.mdx /fr/guides/quickstart

Gib der Standard-Locale keinen eigenen Ordner: Nur die anderen Codes sind Locale-Ordner, daher ist docs/en/ bei en als Standard ganz gewöhnlicher Inhalt, der unter /en/… veröffentlicht wird (und als französischer Fallback unter /fr/en/…). Blume warnt dich, wenn es einen solchen Ordner findet.

Du übersetzt nur die Dateien, die du möchtest – alles andere greift automatisch auf einen Fallback zurück (siehe Fallbacks).

Dateinamen-Suffixe

Du möchtest Übersetzungen lieber neben dem Original behalten? Setze parser: "dot" und benenne Dateien mit einem Locale-Suffix, statt Ordner zu verwenden:

docs/
  guides/quickstart.mdx     ->  /guides/quickstart      (default)
  guides/quickstart.fr.mdx  ->  /fr/guides/quickstart   (French)

Gut geeignet für spärliche Übersetzungen – lege die wenigen übersetzten Seiten daneben ab, ohne den gesamten Baum zu spiegeln.

Gemeinsame Dateien

Für Inhalte, die in jeder Sprache gleich sind – ein Changelog, eine Statusseite – füge einen $-Marker hinzu, damit eine Datei alle Locales ohne Duplikate bedient:

docs/changelog.$.mdx   ->  /changelog and /fr/changelog (same content)
docs/guides/meta.$.ts   (folder meta applied to every locale)

Eine locale-spezifische meta.ts überschreibt die gemeinsame für diese Sprache weiterhin.

URLs der Standard-Locale

Standardmäßig hat die Standard-Locale kein URL-Präfix (/, /guides/quickstart), während andere Locales ein Präfix erhalten (/fr/…). So bleiben die URLs deiner Hauptsprache sauber. Um jeder Locale ein Präfix zu geben, einschließlich der Standard-Locale:

i18n: {
  // …
  hideDefaultLocalePrefix: false, // /en/…, /fr/…
}

Navigation pro Locale

Jede Sprache erhält ihre eigene Seitenleiste, aufgebaut aus den Dateien dieser Locale – so können Übersetzungen in Struktur, Reihenfolge oder Beschriftungen abweichen. Auch meta.ts-Dateien von Ordnern werden pro Locale aufgelöst: Lege unter dem Standard-Parser dir eine meta.ts in fr/guides/ ab, um die französische Gruppe unabhängig zu sortieren. Solange eine Locale keine eigene hat (oder keine gemeinsame meta.$.ts), spiegelt ihre Gruppe die der Fallback-Locale – die meta.ts dieses Ordners und das sidebar.display, das dessen Indexseite setzt –, sodass Seiten, die auf den Fallback zurückgreifen, dieselben Titel, dieselbe Reihenfolge und dieselben einklappbaren Gruppen behalten. Unter dem dot-Parser liegen Übersetzungen neben den Originalen, sodass die meta.ts eines Ordners für jede Locale gilt. Alles andere zur Navigation funktioniert genauso, pro Sprache.

Header-Tabs, Header-Links und der Footer werden konfiguriert und nicht aus dem Inhalt abgeleitet, daher werden ihre Beschriftungen in blume.config.ts lokalisiert. Jede konfigurierte Beschriftung akzeptiert neben der einfachen String-Form auch eine Zuordnung pro Locale ({ en: "Docs", fr: "Documentation" }) und greift für Locales, die du nicht ausgefüllt hast, auf den Eintrag der Standard-Locale zurück: Beschriftungen von Tabs und Dropdowns (Tabs), hervorgehobene Links, Header-Aktionen und der Call-to-Action, Links im Footer, Text und Linktext des Banners sowie benutzerdefinierte Clients im Menü Connect to MCP.

navigation: {
  cta: {
    href: "https://acme.dev/signup",
    label: { en: "Start free", fr: "Essai gratuit" },
  },
},
footer: {
  links: [
    { label: { en: "Pricing", fr: "Tarifs" }, href: "https://acme.dev/pricing" },
  ],
},

Tab-Pfade, Header- und Footer-Links und der Link des Header-Logos wechseln ebenfalls in die Locale der Leserin oder des Lesers, sofern diese Locale die Route bereitstellt, sodass die Oberfläche innerhalb einer Sprache bleibt. Eine Route, die nur die Standard-Locale bereitstellt – eine benutzerdefinierte Seite oder der generierte Changelog-Index –, behält ihren eigenen Pfad, statt auf eine lokalisierte URL zu zeigen, die einen 404 liefern würde.

Fallbacks

Wenn eine Seite noch nicht übersetzt ist, rendert Blume den Inhalt der Fallback-Locale unter der lokalisierten URL – so funktioniert der Link, die Seite wird vollständig vorgerendert, und Suchmaschinen landen nicht in einer Sackgasse. Der Fallback ist standardmäßig deine defaultLocale:

i18n: {
  // …
  fallbackLocale: "en", // default; set to null to 404 instead
}

Fallback-Seiten verweisen mit ihrem kanonischen Link auf die Seite, die sie kopieren, werden aus dem Suchindex, llms.txt und den Seitenlisten von MCP und JSON-API ausgeschlossen und in hreflang nicht als echte Übersetzungen ausgewiesen, sodass unübersetzte Inhalte nicht um das Ranking konkurrieren. Sie erscheinen weiterhin in der Seitenleiste dieser Locale, sodass die Navigation vollständig bleibt – eine Leserin oder ein Leser erreicht jede Seite in jeder Sprache.

Release Notes aus einer githubReleases()-Quelle sind die Ausnahme: Sie werden in einer einzigen Sprache veröffentlicht, daher werden sie nie auf die URLs anderer Locales kopiert und zeigen keinen Sprachumschalter.

Schreibe interne Links so, wie du es in der Standard-Locale tun würdest – [Setup](/guides/setup), <Card href="/guides/setup"> – und zwar in jeder Sprache, auch auf übersetzten Seiten. Wenn eine Seite unter einem Locale-Präfix gerendert wird, verschiebt Blume jeden wurzelrelativen Seitenlink in diese Locale (/fr/guides/setup), sofern die Route dort bereitgestellt wird – als echte Übersetzung oder als Fallback-Seite. Ein Link ohne Variante pro Locale – eine benutzerdefinierte Seite, eine generierte Route oder eine fehlende Übersetzung auf einer Website mit deaktivierten Fallbacks – behält sein ursprüngliches Ziel, statt auf einen 404 zu zeigen, und ein Link, der bereits ein Locale-Präfix trägt (/de/guides/setup), bleibt unangetastet, sodass Links über Locales hinweg explizit bleiben.

Anker wandern mit dem Link mit, daher müssen Heading-IDs über alle Sprachen hinweg übereinstimmen. blume translate erledigt das für dich: Jede übersetzte Überschrift wird mit einem angehängten [#id]-Marker an die ID ihrer Quellüberschrift gebunden. Bei einer von Hand geschriebenen Übersetzung bindest du die Überschriften selbst mit demselben [#custom-id]-Marker – sonst passt #ordering nicht zum automatisch generierten #ordre der französischen Seite, und blume validate meldet die Abweichung gegenüber der übersetzten Seite, auf der eine Leserin oder ein Leser tatsächlich landet.

Übersetzen mit einem Agenten

Du musst die Locales nicht von Hand ausfüllen. blume translate findet jede Seite, die in einer Locale fehlt oder veraltet ist, und übersetzt sie mit einer lokalen Agenten-CLI (Codex oder Claude Code):

blume translate --codex

Blume validiert die Struktur jedes Ergebnisses – Frontmatter, Code-Fences, Links – und schreibt die Dateien selbst; der Agent übersetzt nur Text. Ein eingecheckter Ledger (blume.translations.json) verfolgt, aus welcher Quellrevision jede Übersetzung stammt, sodass erneute Läufe nur ändern, was sich geändert hat, und von Hand geschriebene Übersetzungen unverändert übernommen und nie überschrieben werden. In der CI schlägt blume translate --check fehl, wenn eine Quellseite ihren Übersetzungen vorausgeeilt ist.

Der Sprachumschalter

Wenn i18n aktiviert ist, erscheint automatisch ein Sprachumschalter im Header, generiert aus deinen locales. Für jede Seite verlinkt er die passende Übersetzung in jeder Sprache; wo eine Übersetzung fehlt, verlinkt er die Fallback-Seite und kennzeichnet sie als nicht übersetzt. Sind Fallbacks deaktiviert (fallbackLocale: null), gibt es keine Seite, die er verlinken könnte, daher lässt der Umschalter diese Sprache weg. Es gibt nichts zu konfigurieren. Seiten aus einer GitHub Releases-Quelle sind die Ausnahme: Release Notes gibt es nur in einer Sprache, daher werden diese Seiten ohne Umschalter gerendert.

Routing nach Browsersprache

Um Besucherinnen und Besucher in ihre eigene Sprache zu schicken, aktiviere routeByBrowserLanguage:

i18n: {
  defaultLocale: "en",
  locales: [
    { code: "en", label: "English" },
    { code: "fr", label: "Français" },
  ],
  routeByBrowserLanguage: true,
}

Wer dann von außerhalb der Website auf der Startseite der Standardsprache landet, gelangt zur Startseite in der im Browser bevorzugten Sprache, sofern die Website sie anbietet. Blume probiert jede Sprache, die der Browser bevorzugt, der Reihe nach aus und sucht zuerst nach einem exakt passenden Code, dann nach der Basissprache (fr-CA findet fr). Steht die Standardsprache an erster Stelle, bleibt die Besucherin oder der Besucher auf der Seite. Sobald eine Leserin oder ein Leser über den Sprachumschalter eine Sprache wählt, merkt sich Blume die Auswahl und leitet nicht mehr weiter. Nur die Startseite leitet weiter; ein Link auf jede andere Seite öffnet sich so, wie er geschrieben ist.

Die Weiterleitung läuft im Browser, bevor die Seite dargestellt wird, daher funktioniert sie bei jedem Host, auch bei statischen Builds. Sie ist standardmäßig deaktiviert, weil Suchmaschinen in einer Sprache crawlen: Wenn du sie aktivierst, behalte die hreflang-Alternates bei, die Blume ausgibt, damit die Seiten jeder Sprache weiterhin indexiert werden.

Übersetzte Benutzeroberfläche

Blume liefert integrierte Übersetzungen für seine eigene Oberfläche mit – „Auf dieser Seite“, „Suchen“, „Auf GitHub bearbeiten“ und den Rest – sodass eine Locale mit integriertem Paket von Haus aus eine übersetzte Oberfläche erhält. Du übersetzt nur deine Inhalte.

Pakete gibt es für über 30 Sprachen – Arabisch, Bengalisch, Bulgarisch, Katalanisch, Chinesisch (vereinfacht und traditionell), Kroatisch, Tschechisch, Dänisch, Niederländisch, Finnisch, Französisch, Deutsch, Griechisch, Hebräisch, Hindi, Ungarisch, Indonesisch, Italienisch, Japanisch, Koreanisch, Norwegisch, Persisch, Polnisch, Portugiesisch (und brasilianisches Portugiesisch), Rumänisch, Russisch, Serbisch, Slowakisch, Spanisch, Schwedisch, Thailändisch, Türkisch, Ukrainisch und Vietnamesisch. Sie werden von der Community gepflegt – öffne einen PR, um eine Locale hinzuzufügen oder eine Übersetzung zu verbessern.

Die Pakete decken auch die API-Referenz ab: Überschriften, Schema-Tabellen und das Try-it-Panel einer Operationsseite folgen der Sprache der Seite. Die Beschriftungen, die die Referenz der Seitenleiste hinzufügt – ihre Übersichtsseite und die Gruppen, die sie selbst benennt (Operations, Webhooks und die Arten von GraphQL) –, verwenden die Begriffe der Standard-Locale, da die Referenz in dieser Locale veröffentlicht wird. Nur die Beschriftungen ändern sich, daher bleiben die URLs der Referenz in jeder Sprache gleich.

Fehlende oder nicht mitgelieferte Strings greifen auf die Standard-Locale zurück, dann auf Englisch. Um einen String zu überschreiben oder deine eigene Sprache bereitzustellen, setze i18n.ui, aufgeschlüsselt nach Locale:

i18n: {
  // …
  ui: {
    fr: {
      search: { button: "Rechercher", placeholder: "Rechercher…" },
      page: { previous: "Précédent", next: "Suivant" },
      reference: { tryIt: "Essayer" },
    },
  },
}

SEO

Lokalisiertes SEO wird für dich erledigt – keine Metadaten pro Seite zu schreiben:

  • <html lang> und dir werden anhand der aktiven Locale gesetzt.
  • hreflang-Alternates verlinken jede echte Übersetzung einer Seite, die Suchmaschinen indexieren dürfen (eine Übersetzung mit noindex, eine ausgeblendete oder eine, deren kanonische URL woanders liegt, wird ausgelassen), plus ein x-default, das auf die Standard-Locale zeigt.
  • Kanonische URLs sind locale-korrekt, und JSON-LD führt inLanguage.

Setze deployment.site, damit diese als absolute URLs ausgegeben werden können.

Die Suche ist auf die aktive Sprache beschränkt: Auf einer /fr/…-Seite liefert der Dialog französische Ergebnisse, mit einem Umschalter Alle Sprachen, um auf einmal über alle Locales zu suchen. Der Standardindex (Orama) und der FlexSearch-Index filtern im Browser, Pagefind führt einen Index pro Sprache, und Algolia, Orama Cloud und Typesense führen ein locale-Feld auf jedem Datensatz. Mixedbread kann nicht nach Sprache eingrenzen, daher erstreckt sich damit jede Suche über alle Locales, und der Dialog hat keinen Umschalter. Unter Suche erfährst du, wie die einzelnen Adapter damit umgehen.

Rechts-nach-links

Setze dir: "rtl" auf einer Locale, und Blume spiegelt die gesamte Oberfläche – die Seitenleiste, den Header, das Inhaltsverzeichnis, die Seitennavigation, die Suche und die Menüs – und setzt <html dir> entsprechend. Zwei Dinge bleiben bewusst von links nach rechts: Code-Blöcke (Code liest sich in jeder Sprache LTR) und Fallback-Inhalte – eine unübersetzte Seite behält die Richtung der Sprache, in der sie tatsächlich geschrieben ist, sodass unter einer RTL-Locale angezeigtes Englisch weiterhin korrekt lesbar ist, während die umgebende Oberfläche gespiegelt wird.

Wie geht es weiter

Zuletzt aktualisiert am

War diese Seite hilfreich?