Routing-Strategien, Lazy Loading und hreflang richtig kombiniert
@nuxtjs/i18n ist das De-facto-Standardmodul, um eine Nuxt-Anwendung in mehreren Sprachen auszuliefern, und deckt dabei weit mehr ab als reine Textübersetzung: Es entscheidet über die URL-Struktur pro Sprache, lädt Übersetzungsdateien nur bei Bedarf nach und generiert die für internationales SEO nötigen hreflang-Tags automatisch. Wer die Routing-Strategie einmal falsch wählt, muss später oft die komplette URL-Struktur der Seite migrieren, weshalb sich eine bewusste Entscheidung am Anfang eines Projekts auszahlt.
Inhaltsverzeichnis
- 1. Warum @nuxtjs/i18n für mehrsprachige Nuxt-Apps die Standardwahl ist
- 2. Modul installieren und Grundkonfiguration mit Locales
- 3. Routing-Strategien im Vergleich: Präfix, Subdomain und Domain-pro-Sprache
- 4. prefix vs. prefix_except_default: wann welche Variante passt
- 5. Lazy-Loaded Übersetzungsdateien für bessere Ladezeiten
- 6. SEO-Implikationen: hreflang-Tags automatisch generieren lassen
- 7. Pluralisierte Übersetzungen richtig einsetzen
- 8. Interpolierte Übersetzungen mit dynamischen Werten
- 9. Fallback-Sprachen und fehlende Übersetzungen im Griff behalten
- 10. Zusammenfassung
- 11. FAQ
1. Warum @nuxtjs/i18n für mehrsprachige Nuxt-Apps die Standardwahl ist
Eine mehrsprachige Anwendung braucht mehr als eine Übersetzungstabelle mit Schlüssel-Wert-Paaren. Sie braucht eine konsistente URL-Struktur pro Sprache, damit Suchmaschinen und Nutzer eindeutig erkennen, welche Version einer Seite in welcher Sprache vorliegt, eine Strategie für den Sprachwechsel ohne Verlust des aktuellen Kontexts und eine Möglichkeit, Metadaten wie Title und Description ebenfalls sprachabhängig auszuliefern. @nuxtjs/i18n übernimmt genau diese Aufgaben in einer einzigen, eng mit dem Nuxt-Router integrierten Lösung, statt sie auf mehrere Einzelbibliotheken zu verteilen.
Der Vorteil gegenüber einer selbstgebauten Lösung zeigt sich vor allem bei den Details, die leicht übersehen werden: automatisch generierte Canonical- und Alternate-Links, eine saubere Behandlung von dynamischen Routen mit dem gleichen Namen in unterschiedlichen Sprachen und eine Composable-API, die sich nahtlos in Vue-Komponenten und Nuxt-Serverrouten einfügt. Diese Themen selbst zu bauen, ist machbar, kostet aber deutlich mehr Zeit als die Konfiguration eines etablierten, gut gewarteten Moduls.
2. Modul installieren und Grundkonfiguration mit Locales
Nach der Installation über den Nuxt-Modul-Mechanismus wird @nuxtjs/i18n in der nuxt.config.ts mit einer Liste von Locales konfiguriert, die jeweils einen Sprachcode, einen Anzeigenamen und optional einen eigenen Dateinamen für die Übersetzungsdatei angeben. Zusätzlich legt defaultLocale fest, welche Sprache als Ausgangspunkt gilt, wenn kein anderer Hinweis vorliegt, etwa beim ersten Besuch ohne erkennbare Spracheinstellung im Browser.
Diese Grundkonfiguration bildet das Fundament für alle weiteren Funktionen des Moduls, von der Routing-Strategie bis zur automatischen Spracherkennung. Ein häufiger Anfängerfehler ist, die Locale-Liste nachträglich zu erweitern, ohne die zugehörigen Übersetzungsdateien anzulegen, was dann zur Laufzeit zu fehlenden Texten führt, die im Idealfall über einen konfigurierten Fallback abgefangen werden.
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxtjs/i18n'],
i18n: {
locales: [
{ code: 'de', iso: 'de-DE', name: 'Deutsch', file: 'de.json' },
{ code: 'en', iso: 'en-US', name: 'English', file: 'en.json' },
{ code: 'fr', iso: 'fr-FR', name: 'Francais', file: 'fr.json' },
],
defaultLocale: 'de',
strategy: 'prefix_except_default',
lazy: true,
langDir: 'locales/',
},
})
3. Routing-Strategien im Vergleich: Präfix, Subdomain und Domain-pro-Sprache
Die wichtigste Entscheidung bei der Einrichtung ist die Routing-Strategie, denn sie legt fest, wie die URL für jede Sprache aussieht. Bei präfixbasiertem Routing bekommt jede Sprache (oder alle außer der Standardsprache) ein eigenes Segment am Pfadanfang, etwa /en/produkte statt /produkte, was technisch am einfachsten umzusetzen ist, weil eine einzige Domain für alle Sprachen ausreicht.
Subdomain-Routing verteilt die Sprachen stattdessen auf eigene Subdomains wie en.example.com, während eine vollständig eigene Domain pro Sprache, etwa example.de neben example.com, die stärkste Trennung bietet, aber auch den höchsten Betriebsaufwand verursacht, weil jede Domain eigenes SSL-Zertifikat, eigenes DNS und oft auch eigenes Hosting-Setup braucht. Für die meisten Projekte ist präfixbasiertes Routing der pragmatischste Einstieg, während Domain-pro-Sprache sich vor allem bei stark unterschiedlichen Märkten mit eigener Markenstrategie lohnt.
4. prefix vs. prefix_except_default: wann welche Variante passt
Innerhalb des präfixbasierten Routings bietet @nuxtjs/i18n mehrere Feinabstufungen. Die Strategie prefix versieht ausnahmslos jede Sprache mit einem Präfix, einschließlich der Standardsprache, sodass selbst die deutsche Startseite unter /de/ erreichbar ist. Das schafft maximale Konsistenz zwischen allen Sprachversionen, kann aber für die Hauptzielgruppe unnötig wirken, wenn ein Großteil der Besucher ohnehin nur die Standardsprache nutzt.
prefix_except_default dagegen lässt die Standardsprache ohne Präfix unter der Root-URL laufen und versieht nur die übrigen Sprachen mit einem Segment, was in der Praxis meist die intuitivere Wahl ist, weil sich die bestehende URL-Struktur der Standardsprache nicht ändert. Diese Strategie ist deshalb der häufigste Startpunkt für Projekte, die nachträglich mehrsprachig werden, ohne bestehende SEO-Rankings der Hauptsprache zu gefährden.
5. Lazy-Loaded Übersetzungsdateien für bessere Ladezeiten
Ohne Lazy Loading würden alle Übersetzungsdateien für sämtliche konfigurierten Sprachen in jedes ausgelieferte JavaScript-Bundle wandern, selbst wenn ein Nutzer nur eine einzige Sprache jemals sieht. Bei Projekten mit vielen Sprachen und umfangreichen Übersetzungstexten summiert sich das schnell zu einer spürbaren Menge an ungenutztem Code, der die initiale Ladezeit unnötig verlängert.
Mit der Option lazy: true lädt @nuxtjs/i18n stattdessen nur die Übersetzungsdatei der aktuell aktiven Sprache nach, und lädt bei einem Sprachwechsel zur Laufzeit die neue Datei dynamisch nach, ohne dass ein voller Seiten-Reload nötig wäre. Diese Einstellung sollte in praktisch jedem Projekt mit mehr als zwei Sprachen aktiviert sein, da der Aufwand für die Konfiguration minimal ist, der Effekt auf die Ladezeit aber deutlich spürbar sein kann.
6. SEO-Implikationen: hreflang-Tags automatisch generieren lassen
Suchmaschinen wie Google nutzen hreflang-Tags, um zu erkennen, dass mehrere URLs denselben Inhalt in unterschiedlichen Sprachen darstellen, und um Nutzern in der Suche die passende Sprachversion anzuzeigen. Fehlen diese Tags oder sind sie fehlerhaft verknüpft, kann es passieren, dass Suchmaschinen die falsche Sprachversion in den Ergebnissen zeigen oder mehrere Sprachversionen fälschlich als doppelten Inhalt einstufen.
@nuxtjs/i18n generiert die notwendigen hreflang-Alternate-Links automatisch aus der konfigurierten Locale-Liste und der aktuellen Route, sobald die SEO-Option des Moduls aktiviert ist, und hält sie bei jeder Sprach- oder Routenänderung konsistent. Das entlastet Entwickler von der fehleranfälligen manuellen Pflege dieser Tags, ersetzt aber nicht die Notwendigkeit, tatsächlich vollständig übersetzte Inhalte pro Sprache bereitzustellen, da hreflang nur auf existierende Übersetzungen verweisen sollte.
7. Pluralisierte Übersetzungen richtig einsetzen
Viele Sprachen haben komplexere Pluralregeln als das simple Singular-Plural-Schema des Deutschen oder Englischen, mit mehreren Formen für unterschiedliche Zahlenbereiche. @nuxtjs/i18n baut auf vue-i18n auf und übernimmt dessen Pluralisierungssystem, bei dem ein Übersetzungsschlüssel mehrere durch Pipe-Zeichen getrennte Formen enthalten kann, aus denen anhand einer übergebenen Zahl automatisch die passende Form gewählt wird.
Für Sprachen mit mehr als zwei Pluralformen, etwa Polnisch oder Russisch, lässt sich zusätzlich eine eigene Pluralisierungsregel als Funktion hinterlegen, die die Standardlogik überschreibt. Wer Pluralisierung von Anfang an konsequent über diesen Mechanismus abbildet, statt Texte mit fest eingebauten Zahlwörtern zu schreiben, spart sich später aufwendige Nacharbeiten beim Hinzufügen weiterer Sprachen.
8. Interpolierte Übersetzungen mit dynamischen Werten
Neben statischen Texten enthalten die meisten Anwendungen Meldungen mit dynamischen Werten, etwa einen Nutzernamen oder eine Produktanzahl, die zur Laufzeit in einen Übersetzungstext eingesetzt werden müssen. vue-i18n unterstützt dafür benannte Platzhalter in geschweiften Klammern innerhalb der Übersetzungsdatei, die beim Aufruf über ein Objekt mit den passenden Werten befüllt werden.
Diese Interpolation funktioniert unabhängig von der Wortstellung in der jeweiligen Sprache, was wichtig ist, weil unterschiedliche Sprachen dynamische Werte an unterschiedlichen Stellen im Satz platzieren. Eine hartcodierte String-Verkettung im Anwendungscode würde diese Flexibilität verlieren und müsste für jede Sprache separat angepasst werden, während die Platzhalter-Syntax die Satzstruktur vollständig der Übersetzungsdatei überlässt.
9. Fallback-Sprachen und fehlende Übersetzungen im Griff behalten
In der Praxis sind Übersetzungen selten von Anfang an vollständig, besonders wenn neue Funktionen schneller entwickelt werden als sie übersetzt werden können. Über die fallbackLocale-Option lässt sich festlegen, welche Sprache einspringt, wenn ein Schlüssel in der aktuell aktiven Sprache fehlt, sodass Nutzer statt eines leeren Textes oder eines rohen Schlüsselnamens zumindest eine verständliche Fallback-Übersetzung sehen.
Für die Qualitätssicherung während der Entwicklung bietet sich zusätzlich ein Missing-Handler an, der jeden fehlenden Schlüssel in der Konsole protokolliert, damit Lücken auffallen, bevor sie in Produktion sichtbar werden. Ein systematischer Abgleich der Übersetzungsdateien pro Sprache, etwa über ein einfaches Skript, das alle Schlüssel der Standardsprache mit denen der übrigen Sprachen vergleicht, verhindert, dass Lücken unbemerkt über längere Zeit bestehen bleiben.
| Strategie | URL-Beispiel | Vorteil | Nachteil |
|---|---|---|---|
| prefix | /de/start, /en/start | Konsistent für alle Sprachen | Standardsprache bekommt unnötiges Präfix |
| prefix_except_default | /start, /en/start | Standard-URL bleibt unverändert | Etwas inkonsistente Struktur zwischen Sprachen |
| prefix_and_default | /start und /de/start, /en/start | Beide URL-Formen für Standardsprache erreichbar | Risiko von Duplicate Content ohne sauberes Canonical |
| Subdomain (differentDomains) | de.example.com, en.example.com | Klare Trennung, eigenes Branding möglich | Mehr DNS- und SSL-Verwaltung nötig |
| Domain-pro-Sprache | example.de, example.com | Stärkste Markt- und Markentrennung | Höchster Betriebsaufwand, separates Hosting |
Mironsoft
Vue-Architektur, Composition API und Nuxt-Performance
Vue-Anwendungen, die mit jedem Feature nicht komplizierter werden?
Wir prüfen bestehende Vue- und Nuxt-Projekte auf unstrukturierte Composables, ungenutzte Reaktivität und aufgeblähte Bundles und bauen daraus eine Architektur, die neue Features aufnimmt, ohne die Codebasis unübersichtlicher zu machen.
Architektur-Review
Composables, State-Management und Komponentenstruktur auf Wartbarkeit prüfen.
Performance-Audit
Reaktivitäts-Overhead, Bundle-Größe und Nuxt-Rendering-Strategie systematisch optimieren.
Nuxt-Integration
SSR/SSG-Setup und API-Anbindung robust und typsicher aufbauen.
10. Zusammenfassung
Mehrsprachige Nuxt-Apps mit @nuxtjs/i18n: Das Wichtigste auf einen Blick
Standard-Strategie
prefix_except_default ist meist der pragmatischste Einstieg für bestehende Projekte.
Ladezeit
lazy: true lädt nur die aktive Sprachdatei nach statt alle Sprachen im Bundle.
SEO
hreflang-Alternate-Links werden automatisch aus der Locale-Liste generiert.
Basis
@nuxtjs/i18n baut auf vue-i18n auf, inklusive Pluralisierung und Interpolation.