Alle Artikel
Next.js6 min

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 Sprachen
  • defaultLocale: 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-default sollte auf die internationale Hauptversion zeigen
  • URLs müssen absolute Pfade sein (https://...)
  • ISO 639-1 Sprachcodes verwenden (de, en, nicht de-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.js ist der Start
  • next-intl fü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.

Next.js Internationalisierung i18nNext.jsFreelancerWebentwicklungDüsseldorf