Eine wirklich mehrsprachige Next.js-Website mit next-intl
Lokalisiertes Routing, statisches Rendering, hreflang und Sprachumschaltung: wie ich eine Next.js-Website in zehn Sprachen strukturiere, ohne Performance oder SEO zu opfern.
Warum Mehrsprachigkeit eine echte Architekturfrage ist
Eine Oberfläche zu übersetzen ist leicht. Eine korrekte mehrsprachige Website zu bauen — indexierbar, schnell, wartbar — ist eine Architekturentscheidung, die man am Anfang trifft, nicht am Ende. Dieses Portfolio existiert in zehn Sprachen, und hier sind die Entscheidungen, die im Maßstab tragen.
Das Routing per Locale-Segment
Der robusteste Ansatz mit dem App Router: ein dynamisches [locale]-Segment an der Wurzel. Jede Seite lebt unter app/[locale]/…, und die Sprache wird zu einem URL-Datum erster Ordnung (/fr/projects, /en/projects).
Mit next-intl wird dieses Segment beim Rendern validiert:
- Die unterstützten Locales werden in einer zentralen
routing-Konfiguration aufgelistet. - Eine unbekannte Locale löst ein sauberes
notFound()aus statt einer kaputten Seite. - Die Navigation läuft über einen lokalisierten
Link, der automatisch die richtige Sprache voranstellt.
Der Vorteil: Komponenten fassen die Locale nie „von Hand" an. Sie fragen nach einer Übersetzung, und das System erledigt den Rest.
Die Falle des statischen Renderings
Das ist der Fehler, der in der Produktion am teuersten ist. Wenn Sie die Übersetzungen aufrufen, ohne die Locale zuerst festzulegen, liest next-intl die Request-Header. Das Ergebnis: Die Seite kippt ins dynamische Rendering, und Sie verlieren das statische Prerendering — manchmal mit einem DYNAMIC_SERVER_USAGE-Fehler in der Produktion.
Die Abhilfe passt in eine Zeile, ganz oben auf jeder Seite:
setRequestLocale(locale);
Vor jedem getTranslations aufgerufen, garantiert sie ein vollständig statisches Rendering. Kombiniert mit einem generateStaticParams, das locale × slug kreuzt, prerendert sie jede Seite in jeder Sprache beim Build.
Statische Mehrsprachigkeit ist nicht langsamer als Einsprachigkeit. Sie ist nur anspruchsvoller, was die Reihenfolge der Aufrufe angeht.
hreflang, oder wie man vermeidet, sich selbst Konkurrenz zu machen
Ohne Hinweis behandelt Google Ihre zehn Sprachversionen als zehn rivalisierende Seiten für dieselben Keywords. Die Lösung ist hreflang: Jede Seite deklariert die Gesamtheit ihrer Varianten.
Zwei Stellen müssen synchron bleiben:
- Die Metadaten jeder Seite — über einen
generateAlternates-Helfer, der diealternate-Tags erzeugt. - Die Sitemap — jede URL listet dort ihre Sprachen und ein
x-default.
Die Konsistenz zwischen diesen beiden Quellen sorgt dafür, dass eine spanische Suche auf /es landet und nicht auf /fr.
Die Sprachumschaltung, von der Nutzerseite
Ein Sprachwähler muss die Locale ändern, ohne die aktuelle Seite zu verlieren. Der naive Reflex — den Nutzer zurück auf die Startseite zu schicken — ist frustrierend. Mit dem lokalisierten usePathname von next-intl holt man den Pfad ohne Präfix und gibt ihn in der gewählten Sprache wieder aus. Der Nutzer bleibt genau dort, wo er war.
Was ich mitnehme
- Das
[locale]-Segment an der Wurzel ist das Fundament; alles folgt daraus. setRequestLocalevor den Übersetzungen: nicht verhandelbar, um das Statische zu bewahren.- Die
hreflang-Tags werden doppelt verwaltet (Metadaten und Sitemap), stets synchron. - Die Textrichtung (RTL fürs Arabische) wird auf der Ebene von
<html dir>gesteuert, nicht Seite für Seite.
Gut gemacht, wird Mehrsprachigkeit unsichtbar: Jeder Besucher hat das Gefühl, die Website sei für ihn geschrieben, und Google weiß genau, welche Tür es ihm öffnen muss.