Next.js i18n: SEO-sichere mehrsprachige Websites (hreflang)
Mehrsprachige Websites sind heute Standard für globale Unternehmen. Doch eine Next.js Internationalisierung i18n richtig umzusetzen, bedeutet mehr als nur Texte zu übersetzen. SEO-relevante Aspekte wie hreflang-Tags, URL-Struktur und Content-Delivery müssen von Anfang an stimmen, damit Google deine internationalen Inhalte korrekt indexiert.
In diesem Guide zeige ich dir, wie du Next.js i18n implementierst – mit automatischem Sprach-Routing, korrekten hreflang-Tags und Best Practices für mehrsprachige SEO.
Warum Next.js für Internationalisierung?
Next.js bietet seit Version 10 eingebaute Next.js Internationalisierung i18n-Features:
- Automatisches Routing basierend auf Browser-Sprache
- Sub-Path Routing (
/de/,/en/) oder Domain-Routing (de.example.com) - Locale Detection ohne externe Libraries
- Static Generation pro Sprache für optimale Performance
Das Framework kümmert sich um die technische Basis, du fokussierst dich auf Content und UX.
Next.js i18n Konfiguration: Grundsetup
Die Next.js Internationalisierung i18n beginnt in der next.config.js:
// next.config.js
module.exports = {
i18n: {
locales: ['de', 'en', 'fr'],
defaultLocale: 'de',
localeDetection: true,
},
}
Was passiert hier?
locales: Array aller unterstützten SprachendefaultLocale: Fallback-Sprache (meist dein Hauptmarkt)localeDetection: Automatische Browser-Sprache erkennen
Next.js erstellt jetzt automatisch Routes wie /de/about, /en/about, /fr/about.
Domain-basierte Internationalisierung
Für große internationale Projekte bieten sich separate Domains an:
module.exports = {
i18n: {
locales: ['de', 'en', 'fr'],
defaultLocale: 'de',
domains: [
{
domain: 'example.de',
defaultLocale: 'de',
},
{
domain: 'example.com',
defaultLocale: 'en',
},
{
domain: 'example.fr',
defaultLocale: 'fr',
},
],
},
}
Diese Struktur bietet SEO-Vorteile: Lokale Domains ranken oft besser in ihren Märkten.
Sprach-Routing und useRouter
Next.js stellt die aktuelle Locale über den useRouter Hook bereit:
// components/LanguageSwitcher.tsx
import { useRouter } from 'next/router'
import Link from 'next/link'
export default function LanguageSwitcher() {
const router = useRouter()
const { locales, locale: activeLocale, asPath } = router
return (
<div className="language-switcher">
{locales?.map((locale) => (
<Link
key={locale}
href={asPath}
locale={locale}
className={locale === activeLocale ? 'active' : ''}
>
{locale.toUpperCase()}
</Link>
))}
</div>
)
}
Der locale-Parameter im Link sorgt dafür, dass Next.js automatisch zur richtigen Sprach-Version wechselt – ohne volle Page-Reload.
Content-Verwaltung mit next-intl
Für professionelle Next.js Internationalisierung i18n empfehle ich next-intl. Die Library bietet Type-Safety und verschachtelte Übersetzungen:
npm install next-intl
Erstelle Übersetzungsdateien:
// messages/de.json
{
"nav": {
"home": "Startseite",
"about": "Über uns",
"contact": "Kontakt"
},
"hero": {
"title": "Willkommen bei {company}",
"subtitle": "Wir entwickeln {count, plural, =1 {eine Lösung} other {# Lösungen}}"
}
}
// messages/en.json
{
"nav": {
"home": "Home",
"about": "About",
"contact": "Contact"
},
"hero": {
"title": "Welcome to {company}",
"subtitle": "We build {count, plural, =1 {one solution} other {# solutions}}"
}
}
Integration in _app.tsx:
// pages/_app.tsx
import { NextIntlProvider } from 'next-intl'
import type { AppProps } from 'next/app'
function MyApp({ Component, pageProps }: AppProps) {
return (
<NextIntlProvider messages={pageProps.messages}>
<Component {...pageProps} />
</NextIntlProvider>
)
}
export default MyApp
Verwendung in Komponenten:
// pages/index.tsx
import { useTranslations } from 'next-intl'
import { GetStaticPropsContext } from 'next'
export default function Home() {
const t = useTranslations('hero')
return (
<h1>{t('title', { company: 'ACME Corp' })}</h1>
)
}
export async function getStaticProps({ locale }: GetStaticPropsContext) {
return {
props: {
messages: (await import(`../messages/${locale}.json`)).default
}
}
}
SEO: hreflang-Tags richtig implementieren
Hier wird's kritisch für SEO. Suchmaschinen brauchen hreflang-Tags, um zu verstehen, welche Sprachversionen existieren:
// components/SEOHead.tsx
import Head from 'next/head'
import { useRouter } from 'next/router'
interface SEOHeadProps {
title: string
description: string
}
export default function SEOHead({ title, description }: SEOHeadProps) {
const router = useRouter()
const { locales, locale, asPath } = router
const baseUrl = 'https://example.com'
return (
<Head>
<title>{title}</title>
<meta name="description" content={description} />
{/* Canonical URL */}
<link rel="canonical" href={`${baseUrl}${asPath}`} />
{/* hreflang Tags */}
{locales?.map((loc) => (
<link
key={loc}
rel="alternate"
hrefLang={loc}
href={`${baseUrl}/${loc}${asPath}`}
/>
))}
{/* x-default für unbekannte Sprachen */}
<link
rel="alternate"
hrefLang="x-default"
href={`${baseUrl}${asPath}`}
/>
</Head>
)
}
Best Practices für hreflang:
- Jede Seite muss auf alle Sprachversionen verweisen (inklusive sich selbst)
x-defaultsollte auf die internationale Hauptversion zeigen- URLs müssen absolute Pfade sein (
https://...) - ISO 639-1 Sprachcodes verwenden (
de,en, nichtde-DE)
Locale-spezifische Daten mit getStaticProps
Für statische Seiten mit Next.js Internationalisierung i18n:
// pages/blog/[slug].tsx
import { GetStaticPaths, GetStaticProps } from 'next'
interface BlogPostProps {
post: {
title: string
content: string
locale: string
}
}
export default function BlogPost({ post }: BlogPostProps) {
return (
<article>
<h1>{post.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.content }} />
</article>
)
}
export const getStaticPaths: GetStaticPaths = async ({ locales }) => {
const slugs = ['hello-world', 'nextjs-tutorial']
const paths = locales!.flatMap((locale) =>
slugs.map((slug) => ({ params: { slug }, locale }))
)
return { paths, fallback: false }
}
export const getStaticProps: GetStaticProps = async ({ params, locale }) => {
// Daten aus CMS/Database laden – gefiltert nach locale
const post = await fetchPost(params!.slug as string, locale!)
return {
props: { post },
revalidate: 3600 // ISR nach 1h
}
}
Next.js generiert nun /de/blog/hello-world, /en/blog/hello-world etc. – alle statisch, alle SEO-optimiert.
Performance: Übersetzungen dynamisch laden
Für große Apps mit vielen Übersetzungen:
// lib/loadMessages.ts
export async function loadMessages(locale: string) {
const messages = await import(`../messages/${locale}.json`)
return messages.default
}
// In getStaticProps / getServerSideProps
export const getStaticProps: GetStaticProps = async ({ locale }) => {
return {
props: {
messages: await loadMessages(locale!)
}
}
}
So wird nur die benötigte Sprache geladen – Bundle-Size bleibt klein.
Testing und Debugging
Prüfe deine Next.js Internationalisierung i18n mit diesen Tools:
# Build-Time Analyse
next build
# Prüfe generierte Pfade
ls .next/server/pages/de
ls .next/server/pages/en
# hreflang in Production testen
curl -I https://deine-domain.com/de | grep hreflang
Mit der Google Search Console kannst du hreflang-Fehler identifizieren:
- Internationales Targeting → hreflang-Bericht
- Zeigt fehlende/falsche Tags
Häufige Fehler vermeiden
1. Locale-Detection deaktivieren für spezifische Routes
// next.config.js
module.exports = {
i18n: {
locales: ['de', 'en'],
defaultLocale: 'de',
localeDetection: false, // Manuelles Umschalten forcieren
},
}
2. 404-Seiten pro Sprache
// pages/404.tsx
import { useRouter } from 'next/router'
const messages = {
de: { title: 'Seite nicht gefunden' },
en: { title: 'Page not found' }
}
export default function Custom404() {
const { locale } = useRouter()
const t = messages[locale as keyof typeof messages]
return <h1>{t.title}</h1>
}
Fazit: Production-Ready i18n mit Next.js
Eine saubere Next.js Internationalisierung i18n ist mehr als ein Feature – sie ist Grundlage für internationales Wachstum. Mit den richtigen hreflang-Tags, strukturierten Übersetzungen und Locale-spezifischem Routing schaffst du die Basis für erfolgreiche mehrsprachige Projekte.
Die wichtigsten Takeaways:
- Next.js i18n-Config in
next.config.jsist der Start next-intlfür Type-Safe Translations- hreflang-Tags automatisch in
<Head>generieren - Pro Sprache statische Pages für maximale Performance
Du arbeitest an einem mehrsprachigen Next.js-Projekt? Ich helfe dir gerne bei der technischen Umsetzung – von der i18n-Architektur bis zur SEO-Optimierung.