< BACK Vintage-Drucklettern-Setzkasten mit Reihen von Metallzeichen, sortiert nach Sprache, warmes bernsteinfarbenes Licht, geringe Schärfentiefe

Astro i18n 2026: Das statische mehrsprachige Setup, das rankt

Letztes Frühjahr übergab mir ein Kunde ein Briefing, das mich 2022 zum Stöhnen gebracht hätte. Fünf Sprachen. Elf Märkte. Ein Entwickler. „Wir haben bereits WPML eingerichtet", sagte er mit einer Art von Sicherheit, die dir sagt, dass er sich seine Lighthouse-Werte nie wirklich angeschaut hat.

Ich deaktivierte die WordPress-Installation am zweiten Tag. Baute das Ganze in Astro neu auf. Acht Wochen später waren drei dieser Sprachen auf Seite eins von Google. Die vierte folgte innerhalb des Monats. Diese Erfahrung beendete meine Zusammenarbeit mit WordPress für mehrsprachige Arbeiten praktisch.

Also. Hier ist genau das, was ich jetzt mache.

Warum WordPress Multilingual bei der Performance weiterhin scheitert

Schauen Sie, ich mag es nicht, auf WordPress herumzuhacken. Seahawk hat Hunderte von WP-Seiten gebaut und wird wahrscheinlich noch Hunderte mehr bauen. Aber die Leistungslücke bei mehrsprachigen Projekten ist wirklich schwer zu rechtfertigen.

WPML und Polylang funktionieren beide, indem sie übersetzte Beiträge auf der Datenbankebene generieren und über PHP routen. Jede Anfrage trifft den Server. Selbst mit einem vollständigen Page-Cache (WP Rocket, W3TC, oder was du bevorzugst), kämpfst du immer noch gegen PHP-Initialisierungs-Overhead, Cache-Misses auf Traffic-schwachen Locale-Seiten und hreflang-Verwaltung, die zum Albtraum wird, sobald du mehr als zwei Sprachen hast.

Ich habe einen fünfsprachigen WP-Site eines Kunden gemessen: Time to First Byte von 1,3 Sekunden auf dem italienischen Locale. Derselbe Content, neu aufgebaut in Astro als vollständig statisches HTML: 94ms. Das ist keine marginale Verbesserung. Das ist eine andere Produktkategorie.

Core Web Vitals sind ein bestätigter Ranking-Faktor, und statische Dateien, die von einem CDN-Edge-Node bereitgestellt werden, gewinnen diese Schlacht jedes Mal., and static files served from a CDN edge node simply win that battle every time.

Astros Built-in i18n Routing (Und warum es alles verändert hat)

Astro hat in v3 korrektes i18n-Routing ausgeliefert und es in v4 erheblich verfeinert. Wenn wir 2026 betreiben, ist die API stabil und genuinely angenehm zu bedienen.

Hier ist die grundlegende Einrichtung, die ich verwende. Deine astro.config.mjs bekommt einen i18n-Block:astro.config.mjs gets an i18n block:

`` i18n: { defaultLocale: 'en', locales: ['en', 'de', 'fr', 'it', 'es'], routing: { prefixDefaultLocale: false } } `` i18n: { defaultLocale: 'en', locales: ['en', 'de', 'fr', 'it', 'es'], routing: { prefixDefaultLocale: false } } ``

Diese einzelne Config sagt Astro, English unter / zu servieren, Deutsch unter /de/, Französisch unter /fr/, und so weiter. Kein Plugin. Kein zusätzliches Paket. Es ist eingebaut./, German at /de/, French at /fr/, and so on. No plugin. No extra package. It's baked in.

Das prefixDefaultLocale: false ist absichtlich. Die primäre Zielgruppe der meisten meiner Kunden spricht Englisch, also möchte ich nicht, dass /en/ die kanonische Struktur verschmutzt. Google kann die Beziehung über hreflang herausfinden.prefixDefaultLocale: false is deliberate. Most of my clients' primary audience is English-speaking, so I don't want /en/ polluting the canonical structure. Google can figure out the relationship via hreflang.

Die Dateistruktur, die wirklich skaliert

Hier machen die meisten Tutorials einen Fehler. Sie zeigen dir eine flache pages/[locale]/index.astro und sind fertig. Okay für eine Broschüren-Website. Fällt auseinander, sobald du 40 Routes hast.pages/[locale]/index.astro and call it done. Fine for a brochure. Falls apart the moment you have 40 routes.

Das mache ich stattdessen:

`` src/ pages/ index.astro (English) about.astro (English) [locale]/ index.astro about.astro i18n/ en.json de.json fr.json it.json es.json `` src/ pages/ index.astro (English) about.astro (English) [locale]/ index.astro about.astro i18n/ en.json de.json fr.json it.json es.json ``

Das i18n/-Verzeichnis speichert deine Übersetzungsstrings als flache JSON-Dateien. en.json ist die Quelle der Wahrheit. Ich schreibe jede andere Sprache dagegen. Fehlt ein Key in de.json? Die deutsche Seite fällt auf Englisch zurück für diesen String, anstatt einen Fehler zu werfen, weil ich eine kleine t()-Utility-Funktion hinzufüge, die das Fallback elegant handhabt.i18n/ directory holds your translation strings as flat JSON files. en.json is the source of truth. I write every other locale against it. One key missing in de.json ? The German page falls back to English for that string rather than throwing an error, because I add a small t() utility function that handles fallback gracefully.

The Translation Layer: Keep It Boring

Ich habe Paraglide JS, i18next und ein paar andere ausprobiert. Für Astro Static Builds meine ehrliche Empfehlung: over-engineer das nicht.

Eine einfache Utility-Datei, die Locale-JSON importiert und eine Getter-Funktion zurückgibt, reicht für 90% der Projekte. Paraglide JS von Inlang ist eine Überlegung wert, wenn du typsichere Übersetzungen brauchst und dein Team groß genug ist, um sich um Compile-Time-Fehler bei fehlenden Keys zu kümmern. Für Solo-Arbeit oder kleine Agencies ist es Overhead, den du nicht brauchst.Paraglide JS from Inlang is worth considering if you need type-safe translations and your team is large enough to care about compile-time errors on missing keys. For solo work or small agencies, it's overhead you don't need.

Worauf ich achte: die Übersetzungsdateien flach halten anstatt tief verschachtelt. "hero.cta.button.label" als Key klingt organisiert, bis du ihn um 23 Uhr suchst. "heroCTALabel" ist hässlich, aber auffindbar."hero.cta.button.label" as a key sounds organised until you're searching for it at 11pm. "heroCTALabel" is ugly but findable.

Handling Plurals and Dynamic Strings

Deutsche Pluralisierung wird dich demütigen. Genauso Arabisch, falls du dorthin gehst (ich habe mal einem Kunden bei der Expansion in die VAE geholfen und einen ganzen Nachmittag nur mit Zahlenformatierung verbracht).

Für Plurale verwende ich einen kleinen Inline-Helper:

`` export function plural(count, one, other) { return count === 1 ? one : other; } `` export function plural(count, one, other) { return count === 1 ? one : other; } ``

Primitiv? Ja. Aber das deckt 95 % der Fälle für europäische Sprachen ab. Wenn du dich mit Arabisch, Russisch oder Polnisch beschäftigst, brauchst du echte CLDR-Pluralregeln. Das Unicode-CLDR-Projekt dokumentiert diese umfassend. Erstelle deinen Plural-Helper gegen diese Spezifikationen oder du wirst es falsch machen.The Unicode CLDR project documents these exhaustively. Build your plural helper against those specs or you will get it wrong.

hreflang: Der Teil, bei dem alle falsch liegen

Richtig. Hier lebt mehrsprachige SEO oder stirbt.

hreflang teilt Google mit, welche Version einer Seite es welchem Locale servieren soll. Machst du es falsch, kannst du entweder deine eigenen Rankings kannibalisieren oder servierst die Deutsche Version an französischsprachige Nutzer. Beide Szenarien habe ich schon auf Websites gesehen, die ich übernommen habe.

Die Regeln:

  1. Jede Seite muss hreflang-Tags für jedes Locale enthalten, einschließlich sich selbst.
  2. Die Tags müssen bidirektional sein. Wenn /de/about auf /fr/about verweist, muss /fr/about auch auf /de/about zurückverweisen./de/about references /fr/about , then /fr/about must reference /de/about back.
  3. Füge ein x-default-Tag ein, das auf dein Standard-Locale verweist.x-default tag pointing to your default locale.
  4. Verwenden Sie absolute URLs. Immer.

In Astro generiere ich diese in einer BaseLayout.astro Komponente, die jede Seite importiert. Ich übergebe den aktuellen Pfad, durchlaufe das Locale-Array und gebe die <link rel="alternate"> Tags automatisch aus. Keine manuelle Wartung nötig.BaseLayout.astro component that every page imports. I pass in the current path, loop over the locale array, and spit out the <link rel="alternate"> tags automatically. No manual maintenance.

Das Fehlen des x-default Tags ist der häufigste Fehler, den ich sehe. Googles eigene hreflang-Dokumentation ist wirklich klar dazu. Lesen Sie sie einmal richtig durch.x-default tag is the single most common mistake I see. Google's own hreflang documentation is genuinely clear on this. Read it once properly.

Locale-spezifische Sitemaps

Eine Sitemap mit allen Locales vermischt funktioniert. Aber separate Sitemaps pro Locale (einzeln in der Google Search Console eingereicht) geben dir sauberere Indexierungsdaten und machen es viel einfacher, Crawl-Fehler in einer bestimmten Sprache zu erkennen.

Mein Astro Build generiert fünf Dateien: sitemap-en.xml, sitemap-de.xml und so weiter. @astrojs/sitemap unterstützt das mit der i18n Option ab Werk. Nutzen Sie das.sitemap-en.xml , sitemap-de.xml , and so on. @astrojs/sitemap supports this with the i18n option out of the box. Use it.

Content-Strategie für mehrsprachige statische Websites

Hier ist das, was die meisten Entwickler völlig überspringen: die Übersetzung selbst.

Du kannst ein technisch perfektes Astro-Setup mit fehlerlosem hreflang und einer Sitemap haben, die einen Googler vor Freude weinen lässt. Wenn deine deutsche Kopie durch DeepL gejagt und nie von einem Menschen angefasst wurde, wird die Website in Deutschland nicht gut ranken.

Ich bin da nicht pingelig. Ich nutze DeepL ständig. Es ist ein hervorragender erster Entwurf. Aber für jede Seite, auf der du wirklich ranken willst, muss ein Muttersprachler sie lesen. Nicht unbedingt umschreiben. Einfach lesen, die seltsamen Stellen beheben und bestätigen, dass sich die Formulierung so anhört, wie es ein Deutscher tatsächlich sagen würde.

Seahawk hatte letztes Jahr ein Fintech-Projekt, bei dem der Kunde sieben Sprachen und eine vierwöchige Frist wollte. Wir haben DeepL für die Basis genutzt und dann sieben Freiberufler über Gengo für Überprüfungsdurchläufe eingestellt – zu etwa £0,04 pro Wort. Das Gesamtbudget für Übersetzungen lag unter £800. Die Website rangiert jetzt in vier dieser Märkte in den Top Five. Die Wirtschaftlichkeit geht auf.

Locale-spezifische Metadaten

Titelangaben und Meta-Beschreibungen müssen lokalisiert werden – nicht nur übersetzt. „Best accounting software" bildet sich nicht direkt auf das deutsche Äquivalent ab, weil die Suchvolumina unterschiedlich sind.

Ich halte locale-spezifische Metadaten in den JSON-Übersetzungsdateien unter einem dedizierten Meta-Namespace. Das Page-Template zieht von t('meta.title') und fällt nur auf einen Standard zurück, wenn der Schlüssel fehlt. Das bedeutet, dass ein SEO eine JSON-Datei pro Locale bearbeiten kann, ohne jemals den Code anzufassen.meta namespace. The page template pulls from t('meta.title') and falls back to a default only if the key is missing. This means an SEO can edit one JSON file per locale without ever touching the code.

Deployment: Wo man eine fünfsprachige statische Website hostet

Vercel und Netlify beide handhaben statische Astro-Builds problemlos. Aber für mehrsprachig speziell möchte man Edge-Caching pro Locale und die Möglichkeit, locale-spezifische Header zu setzen.

Ich bin auf Cloudflare Pages standardisiert. Der kostenlose Plan deckt die meisten Client-Budgets ab. Anfragen werden vom nächstgelegenen Edge-Node weltweit serviert – das ist entscheidend, wenn dein italienisches Publikum Dateien von einem Rechenzentrum in Virginia bezieht. Cloudflares Netz hat Nodes in Mailand, Frankfurt, Amsterdam. Der Unterschied in der TTFB für europäische Besucher ist messbar.

Eine Sache, die man ausdrücklich konfigurieren muss: Cache-Control-Header. Statische Dateien sollten lange Cache-TTLs haben (max-age=31536000, immutable für gehashte Assets). HTML-Seiten sollten kürzere TTLs oder eine stale-while-revalidate-Richtlinie haben, besonders wenn du inkrementelle Builds nach Content-Updates machst.Cache-Control headers. Static files should have long cache TTLs ( max-age=31536000, immutable for hashed assets). HTML pages should have shorter TTLs or a stale-while-revalidate policy, particularly if you're doing incremental builds after content updates.

i18n-Builds vor dem Launch debuggen

Ein paar Dinge, die ich bei jedem mehrsprachigen Astro-Build vor dem Pushen in die Produktion überprüfe:

  • Führe astro build lokal aus und inspiziere die dist/ Ausgabe. Jeder Locale-Ordner sollte jede Seite enthalten. Wenn eine Route fehlt, ist der Build-Schritt der richtige Ort, um das abzufangen.astro build locally and inspect the dist/ output. Every locale folder should have every page. If a route is missing, the build step is the place to catch it.
  • Nutze Screaming Frog, um die Preview-Deployment zu crawlen. Filtere nach hreflang. Verwaiste Seiten (Seiten, auf die kein hreflang-Tag verweist) werden sofort sichtbar.Screaming Frog to crawl the preview deployment. Filter by hreflang. Any orphaned pages (pages not referenced by any hreflang tag) show up immediately.
  • Überprüfe das x-default canonical in den Browser DevTools mindestens auf der Startseite und einer inneren Seite.x-default canonical in browser DevTools on at least the homepage and one inner page.
  • Besuche eine Locale-URL manuell in einem Browser, der auf die Sprache dieses Locale eingestellt ist. Klingt offensichtlich. Fängt aber trotzdem Probleme auf.

Das häufigste Build-Zeit-Problem, auf das ich stoße, ist zu vergessen, ein neues Locale nach dem Hinzufügen der JSON-Datei zum astro.config.mjs locales Array hinzuzufügen. Der Build wirft keinen Fehler. Er ignoriert das neue Locale einfach stillschweigend. Nervig.astro.config.mjs locales array after adding the JSON file. The build doesn't error. It just silently ignores the new locale. Annoying.

FAQ

Funktioniert Astros i18n mit Server-Side Rendering (SSR) oder nur mit statischer Ausgabe?

Beides. Astros i18n Routing funktioniert auch im SSR-Modus. Die Hilfsfunktionen getRelativeLocaleUrl() und getAbsoluteLocaleUrl() funktionieren identisch, unabhängig vom Output-Modus. Allerdings: Wenn du vollständig statisch gehst, sind die Performance-Vorteile deutlich größer, weil du vorgebautes HTML ohne Runtime-Kosten auslieferst.getRelativeLocaleUrl() and getAbsoluteLocaleUrl() helper functions work identically regardless of output mode. That said, if you're going fully static, the performance benefits are significantly greater because you're serving pre-built HTML with no runtime cost.

Wie handhabe ich Locale-Erkennung und Redirects für neue Besucher?

Bei statischen Seiten mache ich das auf der CDN/Edge-Ebene, nicht inside Astro. Cloudflare Workers können den Accept-Language Header lesen und zum passenden Locale-Pfad umleiten. Mach das nicht in deiner Astro-App, weil es einen zusätzlichen Request verursacht und die statische Ausgabe nicht-deterministisch macht.Accept-Language header and redirect to the appropriate locale path. Don't do this inside your Astro app because it adds a round trip and makes the static output non-deterministic.

Wie verwaltet man Übersetzungsdateien am besten, wenn die Website wächst?

Lagern Sie sie in der Versionskontrolle neben dem Code, nicht in einem separaten CMS oder einem Übersetzungsverwaltungssystem eines Drittanbieters, bis das Projekt dies wirklich rechtfertigt. Sobald Sie mehr als drei Sprachen und ein aktives Redaktionsteam haben, schauen Sie sich Tolgee oder Localazy an. Beide integrieren sich mit flachen JSON-Dateien und haben GitHub-Synchronisierung. Darunter ist ein gemeinsames Notion-Dokument und manuelle JSON-Updates ehrlich gesagt völlig ausreichend.Tolgee or Localazy. Both integrate with flat JSON files and have GitHub sync. Below that threshold, a shared Notion doc and manual JSON updates is honestly fine.

Kann ich Astro Content Collections mit i18n verwenden?

Ja, und es ist mein bevorzugter Ansatz für inhaltsreiche Blogs. Strukturieren Sie Ihre Content Collection mit Sprache als Pfadsegment: src/content/blog/en/, src/content/blog/de/. Dann filtern Sie nach Sprache in Ihrer getStaticPaths()-Funktion. Jede Sprache erhält beim Build ihr eigenes statisches HTML. Sauber, schnell, und das Redaktionsteam kann Markdown-Dateien verwalten, ohne Komponenten anzufassen.src/content/blog/en/, src/content/blog/de/. Then filter by locale in your getStaticPaths() function. Each locale gets its own static HTML at build time. Clean, fast, and the editorial team can manage markdown files without touching any components.

Schadet es dem SEO, mehrere Sprache-Seiten zu haben, durch doppelte Inhalte?

Nein, vorausgesetzt Ihre hreflang-Implementierung ist korrekt. Google behandelt korrekt annotierte Sprachvarianten als verwandte, aber unterschiedliche Seiten, nicht als Duplikate. Das Risiko liegt in einer fehlerhaften hreflang-Implementierung, insbesondere wenn gegenseitige Annotationen fehlen oder x-default falsch behandelt wird. Beheben Sie diese zwei Dinge, und doppelte Inhalte sind kein Anliegen.incorrectly implementing hreflang, particularly missing reciprocal annotations or incorrect x-default handling. Nail those two things and duplicate content is not a concern.

---

Der Wechsel von dynamischen PHP-gerenderten mehrsprachigen Websites zu vorgefertigten statischen ist nicht wirklich spezifisch für Astro. Es geht darum zu akzeptieren, dass sich die meisten Übersetzungsinhalte nicht stündlich ändern. Bauen Sie einmal, cachen Sie überall, lassen Sie das CDN die Arbeit machen. Astro macht diesen Arbeitsablauf einfach wirklich angenehm, anstatt ein Kampf gegen das Framework zu sein.

Fünf Sprachen, ein Entwickler, acht Wochen. Die Tools sind vorhanden. Nutzen Sie sie.

< BACK