Next.js-SEO

So machen Sie eine Next.js-Website crawlbar, indexierbar und rankbar – die beiden Router, Rendering-Modi (SSG/SSR/ISR/Server Components), die App-Router-Metadata-API, sitemap.ts, robots.ts, next/image, next/link und die Fehler, die sie stillschweigend zerstören.

Erstveröffentlicht: 26. Juni 2026 · Zuletzt aktualisiert: 3. Aug. 2026 · Fortgeschritten
Sprachen

Next.js löst die schwierigsten JavaScript-SEO-Probleme standardmäßig – wenn Sie es richtig verwenden. Die Server Components und SSG/ISR des App-Routers platzieren Inhalte im HTML, sodass es keine Render-Warteschlangenverzögerung gibt; die native Metadata-API löst Titel, Kanonische URLs und Open Graph serverseitig auf; sitemap.ts und robots.ts sind Dateikonventionen. Das Framework bietet die Infrastruktur, schreibt aber keine Ihrer Tags für Sie. Die Fehler sind vorhersehbar: fehlende metadataBase, keine Priorität für das LCP-Bild, aus einem Client Component exportierte Metadaten (tun stillschweigend nichts) und 404-Ansichten, die 200 zurückgeben.

TL;DR — Next.js löst die schwierigsten JavaScript-SEO-Probleme standardmäßig wenn Sie es richtig einsetzen. Der App Router verwendet standardmäßig Server-Komponenten und unterstützt SSG/SSR/ISR – alle liefern gerendertes HTML, sodass es keine Render-Warteschlangenverzögerung gibt. Setzen Sie Metadaten mit der nativen Metadata-API (metadata / generateMetadata) und denken Sie an metadataBase, sonst werden Ihre Kanonischen URLs und OG-Bilder relativ. Verwenden Sie app/sitemap.ts und app/robots.ts, erstellen Sie dynamische Routen mit generateStaticParams vor, setzen Sie priority auf dem LCP-Bild und halten Sie Links als echte next/link-Anker. Der Pages Router ist ebenfalls SEO-fähig über next/head. Die Fehler sind vorhersehbar – und die meisten davon sind nicht Next.js’ Schuld, sondern Ihre.

Wo Next.js passt

Next.js ist ein React-Framework, daher gilt alles in JavaScript-SEO. Was es verdient, einen eigenen Leitfaden zu haben, ist, dass Next.js erstklassige Antworten auf die meisten JS-SEO-Probleme bietet: Server-Rendering, statische Generierung, ein Metadatensystem und Sitemap/Robots-Konventionen. Der schwierige Teil ist nicht, ob Google es lesen kann – Google rendert JavaScript seit Jahren –, sondern die richtige Rendering-Methode zu wählen und die SEO-Grundlagen nicht unverbunden zu lassen. Dies ist ein Spezialfall von Headless-CMS-SEO: Das CMS spielt kaum eine Rolle, die Rendering-Entscheidungen des Frontends entscheiden alles.

Eine Sichtweise, die man im Kopf behalten sollte: „Dies ist eine Next.js-Website“ sagt nicht aus, wie eine einzelne URL ausgeliefert wird. Rendering-Modus, Caching und Server-/Client-Komponenten-Grenzen werden pro Route (manchmal pro Segment) festgelegt – ein Projekt kann eine statische Marketing-Seite, eine SSR-Produktseite und ein Client-Komponenten-Dashboard mischen. Extrapolieren Sie nicht das Verhalten einer Route auf „die gesamte App“; testen Sie die spezifische URL.

Zwei Router, zwei Mechaniken

Next.js hat zwei Router, und sie behandeln SEO unterschiedlich:

  • Pages Router (das ältere Modell) – Datenabruf über getStaticProps / getServerSideProps; Metadaten über <Head> von next/head (oder das next-seo-Paket); keine Server-Komponenten.
  • App Router (v13+, der aktuelle und empfohlene Ansatz) – React-Server-Komponenten standardmäßig; die native Metadata-API (metadata-Export / generateMetadata); Dateikonventionen für app/sitemap.ts und app/robots.ts; generateStaticParams für dynamische Routen. Evidence for this claim The App Router uses Server Components and supports generateStaticParams plus metadata file conventions. Scope: Current Next.js App Router behavior; route rendering can become dynamic based on APIs used. Confidence: high · Verified: Next.js: Server and Client Components Next.js: generateStaticParams

Beide können gut ranken. Der App Router bietet ein saubereres, integriertes Metadatensystem (kein next/head-Gefummel) und Server-Komponenten von Haus aus, weshalb ich bei einem neuen Build darauf zurückgreifen würde. Aber „App Router oder du kannst kein SEO machen“ ist ein Mythos – viele Pages-Router-Websites ranken gut.

Rendering-Modi und was sie für SEO bedeuten

Wie Google mit JavaScript umgeht, ist eine dreiphasige Pipeline – Crawlen, dann eine verzögerte Render-Welle, dann Indexierung. „Alle Seiten mit einem HTTP-Statuscode 200 werden an die Rendering-Warteschlange gesendet.“ Das gesamte Spiel in Next.js besteht darin, einen Modus zu wählen, der Ihre Inhalte vor dieser Render-Welle in das HTML setzt, sodass nichts zu warten bleibt. Evidence for this claim Google crawls, renders, and indexes JavaScript pages, and successful pages can enter the rendering queue. Scope: Google Search processing, not a promise that a URL will be indexed. Confidence: high · Verified: Google: JavaScript SEO basics

  • Static Site Generation (SSG) — Seiten, die zur Build-Zeit vorgerendert werden. HTML ist sofort verfügbar, ohne Render-Warteschlangen-Risiko. Am besten für Inhalte geeignet, die sich nicht jede Minute ändern. generateStaticParams() (App Router) / getStaticPaths() (Pages Router) entscheidet, welche dynamischen Routen vorgebaut werden.
  • Incremental Static Regeneration (ISR) — statische Seiten, die nach einem festgelegten Intervall neu validiert werden (export const revalidate = 3600). Crawler erhalten statisches HTML mit niedrigem TTFB und der Inhalt bleibt aktuell. Eine starke Standardlösung — mit einer Falle: Nach Ablauf des Fensters erhält die nächste Anfrage (möglicherweise Googlebot) weiterhin die veraltete Seite; die aktuelle Version wird erst bei der darauffolgenden Anfrage ausgeliefert. Für wirklich volatile Daten (Preise, Lagerbestände) ist SSR sicherer.
  • Server-Side Rendering (SSR) — HTML wird pro Anfrage gerendert. Crawler erhalten vollständig gerendertes HTML sofort; der Nachteil ist die Serverlatenz, daher sollten Sie TTFB und LCP im Auge behalten. export const dynamic = 'force-dynamic' oder die Verwendung von anfragezeitabhängigen APIs (Cookies, Header) versetzt eine Route in den SSR-Modus.
  • React Server Components (App Router Standard) — rendern auf dem Server und senden HTML; für die Komponente selbst wird kein JavaScript ausgeliefert. Der Inhalt ist in der ersten Antwort enthalten, ohne Hydration-Lücke. Dies ist die beste Standardlösung für SEO. Interaktivität lebt in Client Components, die mit 'use client' markiert sind.
  • Client-Side Rendering (CSR) — wird vollständig im Browser gerendert. Googlebot kann es nach der Render-Welle indexieren (Median etwa 10 Sekunden, aber das 90. Perzentil kann sich auf Stunden ausdehnen), und andere Crawler — Bingbot, KI-Bots, Social-Preview-Bots — erhalten möglicherweise eine leere Seite. Im App Router ist CSR opt-in ('use client'); im Pages Router sollten Sie vermeiden, primäre Inhalte in useEffect abzurufen. Verwenden Sie es nicht für Inhalte, die Sie ranken möchten.

Eine Erinnerung, zu der ich immer wieder zurückkehre: „Googlebot kann es rendern“ ist nicht dasselbe wie „Sie sollten Googlebot dazu bringen, es zu rendern.“ Rendering ist teuer, verzögert und nicht bei allen Crawlern universell verfügbar.

Die Metadata-API (App Router)

Die Metadata-API ist nur für Server Components — Metadaten werden auf dem Server aufgelöst, bevor die Seite gerendert wird, sodass sie im initialen HTML landen. Exportieren Sie metadata aus layout.js oder page.js:

export const metadata: Metadata = {
  title: 'My Page',
  description: 'Page description',
}

Oder, wenn die Tags von abgerufenen Daten abhängen, verwenden Sie generateMetadata():

export async function generateMetadata({ params }) {
  const post = await getPost(params.slug)
  return { title: post.title, description: post.description }
}

Die Felder, die für SEO relevant sind:

  • title — unterstützt einen String, eine Vorlage ('%s | Brand'), einen Standardwert und eine absolute Überschreibung. Setzen Sie die Vorlage einmal im Root-Layout, und die Seitentitel übernehmen sie.
  • description, alternates.canonical (die korrekte Methode, um im App Router ein Canonical zu setzen), openGraph (Bilder müssen auf absolute URLs auflösen), twitter (auch von LinkedIn- und Slack-Vorschauen verwendet) und robots (index/follow plus googleBot-spezifische Direktiven wie max-snippet, max-image-preview).
  • metadataBaseerforderlich, damit Canonical- und OG-Bild-URLs korrekt aufgelöst werden. Das Vergessen ist der häufigste Next.js-Metadaten-Bug: Relative URLs gelangen in Ihre Canonical- und Open-Graph-Tags, brechen Social-Previews und verwässern Canonical-Signale.

Ein Beispiel für eine Titelvorlage:

// app/layout.tsx
export const metadata: Metadata = {
  metadataBase: new URL('https://example.com'),
  title: { template: '%s | Brand Name', default: 'Brand Name' },
}
// app/blog/page.tsx
export const metadata: Metadata = { title: 'My Blog Post' }
// Output: <title>My Blog Post | Brand Name</title>

Zwei Stolperfallen. Erstens werden Metadaten flach vom Layout zur Seite zusammengeführt — ein verschachteltes Objekt wie openGraph, das in einem Kindsegment definiert ist, ersetzt das des übergeordneten Elements vollständig, sodass ein Seiten-Level-openGraph: { title: 'Home' } stillschweigend alle openGraph.images verwirft, die im Layout gesetzt wurden. Zweitens — und das beißt die Leute — metadata funktioniert nur in Server Components. Wenn Sie es aus einer 'use client'-Datei exportieren, tut es stillschweigend nichts.

Streaming-Metadaten. Für dynamisch gerenderte Seiten kann generateMetadata die Metadaten nach dem initialen HTML streamen. Googlebot führt JavaScript aus und prüft das vollständige DOM, daher funktionieren gestreamte Metadaten für Google. Aber Next.js erkennt „HTML-beschränkte Bots“ – Bingbot, Twitterbot, Slackbot, facebookexternalhit – und liefert ihnen blockierende Metadaten im <head> aus. Laut der Next.js-Dokumentation: „streaming metadata is disabled for bots and crawlers that expect metadata to be in the <head> tag.“ (Übersetzung) „Streaming-Metadaten sind für Bots und Crawler deaktiviert, die Metadaten im <head>-Tag erwarten.“ Dies geschieht automatisch; keine Konfiguration erforderlich. Es ist ein Detail, das fast kein konkurrierender Leitfaden abdeckt, und es ist der Grund, warum Streaming-Metadaten kein Risiko für Bots darstellen, die nicht darauf warten können. Vorgerenderte Seiten sind ein völlig anderer Fall – dort werden Metadaten zur Build-Zeit aufgelöst, es gibt also keinen Stream, um den man sich kümmern müsste. Dieses Verhalten ist versionsspezifisch (aktuell ab Next.js 16.2.10); überprüfen Sie die generateMetadata-Dokumentation erneut, wenn Sie ein Upgrade durchführen. Und da die Auslieferungspfade je nach Einstiegspunkt unterschiedlich sind, verifizieren Sie Metadaten auf zwei Arten, nicht nur auf eine: eine direkte/Produktionsanfrage (curl -I oder Quelltext anzeigen) und eine clientseitige Navigation zu derselben Route – der Head kann sich zwischen beiden unterschiedlich aktualisieren.

Evidence for this claim Prerendered Next.js pages do not use streaming metadata because metadata is resolved at build time in the documented path. Scope: route output, metadata and deployment Confidence: high · Verified: Metadata and OG images

Metadaten mit next/head (Pages Router)

Beim Pages Router befinden sich Metadaten in <Head> von next/head:

import Head from 'next/head'

export default function Page() {
  return (
    <>
      <Head>
        <title>My Page | Brand</title>
        <meta name="description" content="Description" />
        <link rel="canonical" href="https://example.com/my-page" />
      </Head>
      {/* page content */}
    </>
  )
}

Legen Sie Titel und Beschreibung pro Seite fest (nicht nur in _app.js) und setzen Sie einen kanonischen Link auf jede Seite, einschließlich paginierter Varianten. Das Paket next-seo standardisiert dies mit einer <NextSeo>-Komponente und Structured-Data-Hilfsfunktionen. Die Migration zum App Router bedeutet hauptsächlich, next/head und next-seo gegen den nativen metadata-Export einzutauschen.

Benötigen Sie das Paket next-seo? Es ist ein Drittanbieter-Plugin (nicht Teil von Next.js selbst) – aktiv gepflegt, zum Zeitpunkt dieses Schreibens in Version 7.2.0, nicht archiviert. Seine eigene Dokumentation ist explizit darüber, wo es passt: Für Standard-Meta-Tags im App Router empfiehlt die README des Pakets, die eingebaute generateMetadata/metadata-Exportfunktion von Next.js anstelle von <NextSeo> zu verwenden; beim Pages Router ist <NextSeo> weiterhin eine sinnvolle Komfortschicht über next/head. Der einzige Anwendungsfall im App Router, den das Paket weiterhin abdeckt, sind seine JSON-LD-Hilfskomponenten (ArticleJsonLd, FAQPageJsonLd usw. mit useAppDir), die einige Teams gegenüber handgeschriebenem <script type="application/ld+json"> bevorzugen. Fazit: Bei einem neuen App-Router-Build greifen Sie zuerst zur nativen Metadata-API – das Paket ist optional, keine Notwendigkeit, und seine eigenen Maintainer sagen das auch.

Sitemaps

Im App Router ist app/sitemap.ts eine Dateikonvention, die /sitemap.xml ausgibt:

import type { MetadataRoute } from 'next'

export default function sitemap(): MetadataRoute.Sitemap {
  return [
    { url: 'https://acme.com', lastModified: new Date(), priority: 1 },
    { url: 'https://acme.com/blog', lastModified: new Date(), priority: 0.8 },
  ]
}

Für große Websites teilt generateSitemaps() in mehrere Dateien auf (Googles Limit liegt bei 50 000 URLs pro Sitemap), die jeweils unter /.../sitemap/[id].xml bereitgestellt werden. Die Sitemap-Ausgabe unterstützt auch Bild-Sitemaps, Video-Sitemaps und lokalisierte alternates.languages. Beim Pages Router verwenden Sie next-sitemap oder generieren pages/sitemap.xml.js mit getServerSideProps.

robots.txt

app/robots.ts generiert Ihre Robots-Datei programmatisch:

export default function robots(): MetadataRoute.Robots {
  return {
    rules: [{ userAgent: '*', allow: '/', disallow: '/private/' }],
    sitemap: 'https://acme.com/sitemap.xml',
  }
}

Regeln pro User-Agent und mehrere Sitemaps werden unterstützt. Der Pages Router verwendet eine statische public/robots.txt. Die Regel, die Sie auf keinem Router falsch machen dürfen: blockieren Sie niemals Ihr JavaScript oder CSS – Google rendert nicht aus blockierten Dateien, und bei einem JS-Framework kann das die Seite vollständig leeren.

next/image und Core Web Vitals

next/image ist einer der stärksten Gründe, das Framework für SEO zu verwenden. Es lädt Bilder unterhalb des Falzes lazy, erfordert width/height (oder fill), sodass es Platz reserviert und Layout-Shift / CLS verhindert, liefert WebP/AVIF automatisch aus und erzeugt ein korrektes srcset aus der sizes-Prop. Die mit Abstand wichtigste CWV-Optimierung ist die priority-Prop auf Ihrem Hero-/Above-the-Fold-Bild, die es für ein schnelleres LCP vorlädt:

<Image src="/hero.jpg" width={1200} height={630} priority alt="Hero" />

Das Vergessen von priority auf dem LCP-Bild ist der häufigste Next.js-CWV-Fehler – und CWV-Probleme sind auf echten Next.js-Websites weit verbreitet (siehe den Stats-Tab für die Salt-Agency-Daten). alt ist erforderlich: leer für dekorative Bilder, beschreibend für Inhaltsbilder.

next/link rendert standardmäßige <a href>-Anker im HTML, sodass Google sie normal verfolgt, und es fügt clientseitige Navigation sowie Hintergrund-Prefetching von Links im Viewport in der Produktion hinzu. Die SEO-Regel ist einfach: Verwenden Sie next/link für interne Links und ersetzen Sie niemals einen onClick-Handler oder eine JavaScript-Navigation, die keinen echten Anker erzeugt – solche Links sind nicht crawlbar. Verwenden Sie prefetch={false} bei Links mit geringem Wert, um Bandbreite zu sparen, falls nötig.

Dynamische Routen und generateStaticParams

generateStaticParams() teilt Next.js mit, welche dynamischen Routen zur Build-Zeit vorgerendert werden sollen:

// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
  const posts = await getPosts()
  return posts.map((post) => ({ slug: post.slug }))
}

So erstellte Seiten sind vollständig statisches HTML – am besten für SEO. Ohne diese Funktion werden dynamische Routen standardmäßig bei Bedarf (SSR) gerendert, was in Ordnung ist, aber Serverlatenz wieder einführt. Kombinieren Sie es mit revalidate (ISR) für Inhalte, die regelmäßig aktualisiert werden. Stellen Sie sicher, dass alle wichtigen dynamischen URLs in generateStaticParams enthalten sind, damit nichts auf die Render-Warteschlange warten muss.

Strukturierte Daten (JSON-LD)

Die Metadata-API hat kein Feld für strukturierte Daten – Sie injizieren JSON-LD als <script> in einer Server-Komponente, wodurch es im servergerenderten HTML ohne Client-Bundle-Kosten bleibt:

const jsonLd = { '@context': 'https://schema.org', '@type': 'Article', /* … */ }
return <script type="application/ld+json"
  dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />

Article/BlogPosting, BreadcrumbList, Product und FAQPage sind die üblichen Typen. Validieren Sie nach jeder Rendering-Änderung mit dem Rich-Results-Test.

Häufige Next.js-SEO-Fehler

Abgeleitet aus echten Audits und den obigen Mustern:

  1. Fehlende oder relative Kanonische – oft durch ein vergessenes metadataBase, das auch OG-Bild-URLs bricht.
  2. Kein priority auf dem LCP-Bild – der größte CWV-Fehler.
  3. 404-Ansichten, die 200 zurückgeben – verwenden Sie die eingebaute notFound(), um einen echten Status zurückzugeben; Soft-404s sind auf Next.js-Websites weit verbreitet.
  4. metadata aus einer Client-Komponente exportiert – tut stillschweigend nichts; es ist nur für Server-Komponenten.
  5. CSR für primäre Inhalte – das Abrufen kritischer Inhalte in useEffect bedeutet, dass Nicht-Google-Crawler leere Seiten erhalten.
  6. Hash-(#) Routing anstelle der History-API – diese Ansichten sind nicht separat crawlbar.
  7. generateStaticParams nicht exportiert – dynamische Routen werden bei Bedarf gerendert, anstatt vorgebaut zu werden.
  8. openGraph durch Layout-Vererbung überschrieben – Kindsegmente ersetzen, nicht zusammenführen.
  9. Blockieren von JS/CSS in robots.txt oder über eine Content Security Policy, die das Headless-Chrome von Googlebot daran hindert, Skripte zu laden – testen Sie mit URL Inspection.

Bereitstellungshinweise

Next.js wird von Vercel entwickelt; das Hosting dort bietet eine enge Integration (Edge-CDN für statische und ISR-Seiten, gute TTFB), ist aber nicht erforderlich. Definieren Sie permanente Weiterleitungen in redirects() in next.config.js (gibt 308 oder 301 mit permanent: true zurück) für zuverlässige Signale an Crawler, setzen Sie Sicherheits- und Cache-Header über headers() und verwenden Sie X-Robots-Tag-Antwortheader für pfadbasierte noindex-Regeln, wenn die robots-Metadaten pro Seite umständlich sind.

Was wo zu prüfen ist. Cache-Status, Statuscodes, Weiterleitungen und gestreamte Metadaten erscheinen nicht alle im selben Test – eine Route kann in einer Prüfung gut aussehen und in einer anderen dennoch defekt sein:

PrüfungWo nachsehenWarum sie von dem abweichen kann, was Sie gerendert sehen
Cache-/RevalidierungsalterAntwort-Header bei einer direkten Anfrage (curl -I)ISR kann direkt nach Ablauf des Fensters eine veraltete Seite ausliefern
Direkter HTTP-Statuscurl -I auf der Produktions-URL, nicht auf der gerenderten OberflächeEine „nicht gefunden“-Ansicht ohne notFound() gibt weiterhin 200 zurück
Redirect-VerhaltenDer tatsächliche Kontext, der ihn auslöst – redirect() in einer Server Action, einem Route Handler, im Vergleich zu einem clientseitigen onClickStatuscode und Antwortpfad unterscheiden sich je nach Aufrufkontext, nicht nur nach Ziel
Gestreamte MetadatenDirekte Anfrage und clientseitige Navigation zur selben RouteNormale Clients können gestreamte Metadaten erhalten; auf HTML beschränkte Bots erhalten blockierende Metadaten; die beiden Pfade sind nicht identisch
Clientseitige ÜbergängeIn der App navigieren und dann das <head> erneut prüfenEine Route, die beim ersten Laden korrekt ist, kann nach einem Client-Übergang abweichen

Nichts davon ist durch das Framework garantiert – Next.js bietet Ihnen die Mechanismen (redirects(), notFound(), Revalidierung, Streaming), aber Cache-Schlüssel, Invalidierung, Vorschauzustand und Deployment-Konfiguration liegen weiterhin in Ihrer Verantwortung, sie richtig einzustellen und in der Produktion zu testen, nicht nur lokal.

Noch ein letzter Hinweis zum dynamischen Rendering – vorgefertigtes HTML an Bots und JavaScript an Nutzer auszuliefern. Google hat dies als Empfehlung verworfen: “dynamic rendering was a workaround and not a long-term solution.” (Übersetzung) „Dynamisches Rendering war eine Notlösung und keine langfristige Lösung.“ Sie brauchen es auf Next.js ohnehin nicht – SSR, SSG, ISR und Server Components platzieren Inhalte nativ im HTML. Erwähnen Sie es, um es in einem Audit zu erkennen; bauen Sie nicht darauf auf.

Der Idealfall: App Router + Server Components + ISR + die Metadata API (mit metadataBase) + next/image mit priority. Wenn Sie das richtig umsetzen, ist der Großteil der Next.js-SEO abgedeckt.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.