
Technical SEO: SPAs & Next.js sichtbar machen
while.chat selbst hatte das Problem. Die Seite war live, die Artikel waren fertig, und Google indexierte genau einen einzigen Treffer. Nicht wegen schlechter Inhalte. Sondern weil ein JavaScript-gerendetes Frontend für Googlebots strukturell schwer zugänglich ist, wenn Server-Side Rendering fehlt oder unvollständig konfiguriert ist.
Single Page Applications und moderne React-Frameworks haben die Art verändert, wie Websites gebaut werden. Next.js, Nuxt, Remix, SvelteKit, diese Frameworks sind produktiv, schnell in der Entwicklung und erzeugen hervorragende Nutzer-Erlebnisse. Was sie nicht automatisch erzeugen: eine SEO-freundliche Architektur. Der Grund ist technisch präzise: Googlebots rendern JavaScript, aber langsamer, weniger vollständig und unter anderen Bedingungen als echte Nutzer-Browser. Was ein Nutzer sieht und was Googlebot crawlt, kann erheblich divergieren.
Dieser Artikel erklärt die technischen Ursachen, die kritischsten Fehler und den pragmatischen Fix-Pfad, spezifisch für Next.js, aber übertragbar auf jeden SPA-Stack.
// 01 / 06Warum SPAs und SEO grundsätzlich in Konflikt stehen
Klassische Websites liefern bei jedem Request vollständiges HTML: Server verarbeitet Anfrage, gibt fertiges HTML zurück, Browser rendert. Googlebot liest das HTML und indexiert den Inhalt. Einfach.
Eine Single Page Application funktioniert anders: Der Server liefert eine minimale HTML-Shell mit einem JavaScript-Bundle. Der Browser lädt das Bundle, führt es aus, und erst dann entsteht der sichtbare Content, durch JavaScript, das die DOM-Struktur dynamisch aufbaut.
Google hat das JavaScript-Rendering-Problem erkannt und verbessert kontinuierlich seine Crawling-Infrastruktur. Aber selbst 2026 gilt: Server-Side Rendering ist zuverlässiger als auf Googlebots JS-Execution zu vertrauen. Die Google-eigene Dokumentation empfiehlt explizit SSR oder Static Generation für SEO-kritische Inhalte.
// 02 / 06Die vier Rendering-Strategien und ihre SEO-Implikationen
Rendering-Strategien im Vergleich Strategie Wie SEO Ideal für CSR
Client-Side Rendering JS im Browser rendert alles Kritisch Apps hinter Login, keine SEO-Anforderung SSR
Server-Side Rendering Vollständiges HTML per Request Sehr gut Dynamische Seiten (User-Content, Echtzeit) SSG
Static Site Generation HTML beim Build generiert Optimal Blog, Docs, Marketing-Seiten ISR
Incremental Static Regen. SSG + zeitgesteuerte Neugenerierung Sehr gut Häufig aktualisierte statische Inhalte Hybrid
SSR + SSG gemischt Pro Route konfigurierbar Gut (wenn richtig) Große Apps mit unterschiedlichen Anforderungen
Für while.chat und vergleichbare Blogs mit statischen Artikeln ist SSG die richtige Wahl: Artikel werden beim Build zu HTML kompiliert, Vercel liefert fertige HTML-Dateien aus dem CDN, Googlebot bekommt vollständiges HTML in Welle 1. Kein JavaScript-Rendering erforderlich.
// 03 / 06Next.js SEO: Die kritischen Konfigurationspunkte
Next.js macht vieles richtig, aber die SEO-Defaults sind nicht automatisch optimal. Diese Punkte müssen explizit konfiguriert werden.
1. Metadata API (App Router, Next.js 13+)
Im App Router erfolgt Metadaten-Konfiguration über das metadata-Objekt oder die generateMetadata-Funktion, nicht mehr über next/head.
// app/posts/[slug]/page.tsx
export async function generateMetadata({ params }) {
const post = await getPost(params.slug);
return {
title: post.title,
description: post.excerpt,
openGraph: {
title: post.title,
description: post.excerpt,
url: `https://while.chat/posts/${params.slug}`,
type: 'article',
},
alternates: {
canonical: `https://while.chat/posts/${params.slug}`,
},
};
}
2. generateStaticParams für SSG
Ohne generateStaticParams rendert Next.js dynamische Routen on-demand (SSR). Für Blog-Artikel, die sich selten ändern, ist SSG die richtige Wahl:
// app/posts/[slug]/page.tsx
export async function generateStaticParams() {
const posts = await getAllPosts();
return posts.map(p => ({ slug: p.slug }));
}
// Beim Build werden alle Slugs als statisches HTML generiert
3. Sitemap.xml dynamisch generieren
Next.js 13.3+ unterstützt eine sitemap.ts-Datei im App Directory, die automatisch eine /sitemap.xml-Route erzeugt:
// app/sitemap.ts
import { getAllPosts } from '@/lib/posts';
export default async function sitemap() {
const posts = await getAllPosts();
return [
{ url: 'https://while.chat', lastModified: new Date(), priority: 1 },
{ url: 'https://while.chat/artikel', lastModified: new Date(), priority: 0.9 }...posts.map(p => ({
url: `https://while.chat/posts/${p.slug}`,
lastModified: new Date(p.updatedAt),
priority: 0.8,
})),
];
}
4. robots.txt
// app/robots.ts
export default function robots() {
return {
rules: { userAgent: '*', allow: '/' },
sitemap: 'https://while.chat/sitemap.xml',
};
}
// 04 / 06Core Web Vitals: Was im SPA-Kontext besonders wichtig ist
Core Web Vitals sind Google-Ranking-Faktoren seit Mai 2021. Im SPA-Kontext versagen einige klassische Optimierungsansätze, weil sie für serverseitig gerenderte Seiten entwickelt wurden.
LCP, Largest Contentful Paint
Ziel: unter 2,5 Sekunden. Das größte sichtbare Element (meist Hero-Bild oder H1) muss schnell laden. Häufiger SPA-Fehler: Das LCP-Element ist ein dynamisch geladenes Bild ohne priority-Flag. In Next.js:
- Hero-Bild mit
<Image priority />markieren
- Fonts mit
preload-Link im Head
- Critical CSS inline im Initial-HTML
INP, Interaction to Next Paint
Ersetzt CLS seit März 2024. Ziel: unter 200ms. Misst die Reaktionszeit auf User-Inputs. In React-Apps häufige Ursachen: schwere Re-Renders durch unkontrollierte State-Updates, synchrone Event-Handler, lange JavaScript-Tasks. Fixes:
- React
useTransitionfür nicht-kritische Updates
- Code-Splitting mit dynamischen Imports
- Debounce auf häufige Event-Handler
CLS, Cumulative Layout Shift
Ziel: unter 0,1. Visuelle Stabilität während des Ladens. In SPAs typische Ursachen: Bilder ohne definierte Dimensionen, dynamisch eingefügte Elemente (Consent-Banner, Cookie-Notices), Web-Fonts die FOUT erzeugen. Fixes:
- Immer
widthundheightauf<Image>
- Fonts mit
font-display: optionaloderswap
- Consent-Banner per CSS reservierter Raum
TTFB, Time to First Byte
Kein offizieller CWV, aber starker Ranking-Indikator. Ziel: unter 800ms. Bei Vercel-Deployment: Edge-Functions und CDN-Caching halten TTFB typischerweise unter 100ms für statische Assets. Kritisch wird es bei SSR-Routen mit Datenbank-Queries ohne Caching.
- Statische Routen bevorzugen (SSG statt SSR)
unstable_cachefür Datenbankabfragen
- Edge-Runtime für leichte API-Routes
// 05 / 06Strukturierte Daten in Next.js implementieren
Schema.org JSON-LD ist für Generative Engine Optimization genauso wichtig wie für klassisches SEO, und in Next.js einfach zu implementieren, wenn der richtige Ort dafür bekannt ist.
// Artikel-Seite: JSON-LD als Script-Tag im Head
export default function PostPage({ post }) {
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Article',
headline: post.title,
description: post.excerpt,
author: { '@type': 'Person', name: 'Max Goette' },
datePublished: post.publishedAt,
dateModified: post.updatedAt,
};
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
{/* Artikel-Content */}
</>
);
}
Für FAQ-Seiten das FAQPage-Schema ergänzen:
const faqSchema = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: faqs.map(f => ({
'@type': 'Question',
name: f.question,
acceptedAnswer: { '@type': 'Answer', text: f.answer },
})),
};
// 06 / 06Die häufigsten Technical-SEO-Fehler im SPA-Stack
Diese Probleme treten in der Mehrheit der SPA-Projekte auf, die noch nicht explizit auf SEO optimiert wurden.
Fehler 1, Dynamische Redirects ohne 301-Status: In Next.js können Redirects in next.config.js mit explizitem permanent: true als 301 konfiguriert werden. Client-seitige Redirects (via useRouter().push()) übertragen keinen SEO-Wert und sollten für SEO-kritische URLs nicht genutzt werden.
Fehler 2, Duplicate Content durch trailing Slash: /artikel und /artikel/ sind für Google unterschiedliche URLs ohne Canonical-Tag. Next.js-Default: trailingSlash: false in next.config.js setzen und in der Sitemap konsequent eine Variante nutzen.
Fehler 3, Fehlende oder falsche Canonical-Tags: Besonders bei paginierten Inhalten (/artikel?page=2) müssen Canonical-Tags auf die Hauptseite zeigen, oder jede Seite hat ihren eigenen Canonical. Beides ist valide, Inkonsistenz nicht.
Fehler 4, JavaScript-Fehler blockieren Indexierung: Ein einzelner unbehandelter JS-Fehler kann dazu führen, dass Googlebot die Seite nicht vollständig rendert. Fehler-Boundaries in React implementieren und Core-Rendering-Fehler in der Google Search Console überwachen (Abschnitt "Abdeckung").
Fehler 5, Sitemap nicht in GSC eingereicht: Eine vorhandene Sitemap wird von Google nicht automatisch gefunden. GSC → Sitemaps → Sitemap-URL einreichen. Nach jedem Major-Deployment neu validieren.
Häufige Fragen zu Technical SEO und SPAs
Quellen
- Google Search Central (2025). JavaScript SEO basics. developers.google.com
- Next.js Docs (2026). Metadata API, generateStaticParams, Sitemap. nextjs.org/docs
- Google Search Central (2025). Core Web Vitals. developers.google.com
- web.dev (2025). Interaction to Next Paint (INP). web.dev
- Vercel Docs (2026). Edge Network, Deploy Previews, Crawling. vercel.com/docs
- Schema.org (2026). Article, FAQPage, BreadcrumbList. schema.org
// micro-journal
Welche deiner Seiten sieht Googlebot wirklich?
Ein Satz reicht. Das Journal bleibt lokal in deinem Browser — kein Konto, kein Server.
notierenMG
Max Götte
SEO Strategist · Founder · while.chat
SEO-Berater aus Bochum. Spezialisiert auf technisches SEO, Local SEO und Generative Engine Optimization für KMU im DACH-Raum. Von Audit über Content-Strategie bis Local SEO, evidenzbasiert, ohne Hype-Versprechen.
FAQ
Kann Googlebot JavaScript-SPAs nicht indexieren?
Googlebot kann JavaScript rendern, aber langsamer und weniger zuverlässig als ein Browser. Google unterscheidet zwei Crawling-Wellen: Welle 1 liest das initiale HTML sofort, Welle 2 rendert JavaScript verzögert (Stunden bis Tage). Inhalte, die erst nach JS-Execution sichtbar sind, werden später und weniger zuverlässig indexiert. Für neue Seiten und häufige Updates ist SSR oder SSG deutlich verlässlicher als auf Welle 2 zu warten.
Was ist der Unterschied zwischen SSR und SSG in Next.js für SEO?
Beide liefern vollständiges HTML an Googlebot. Der Unterschied: SSG generiert das HTML beim Build-Zeitpunkt, jeder Request bekommt das gleiche, gecachte HTML vom CDN. SSR generiert das HTML bei jedem Request neu. Für SEO-Zwecke sind beide gleichwertig. Für Performance ist SSG besser (TTFB nahe 0ms vom CDN), für dynamische Inhalte (personalisierte Seiten, Echtzeit-Daten) ist SSR notwendig.
Wie überprüfe ich, ob meine Next.js-Seite korrekt gecrawlt wird?
Drei Methoden: Erstens, "Seitenquelltext anzeigen" im Browser, vollständiges HTML im Source bedeutet SSR/SSG funktioniert. Zweitens, Google Search Console → URL-Prüfung → URL eingeben → "Indexierte Seite abrufen", zeigt exakt, was Googlebot sieht. Drittens, Google Search Console → Abdeckung → "Entdeckt, aber nicht indexiert" und "Gecrawlt, aber nicht indexiert" analysieren, häufig symptomatisch für JS-Rendering-Probleme.
Brauche ich eine XML-Sitemap wenn meine Next.js-App alle Links intern verlinkt?
Ja. Auch bei vollständiger interner Verlinkung beschleunigt eine Sitemap die Entdeckung neuer Seiten erheblich. Besonders wichtig bei Neu-Deployments und nach der Indexierungs-Reinigung (z.B. nach Slug-Änderungen). Die Sitemap sollte in Google Search Console eingereicht und nach jedem Major-Deployment validiert werden.
Hat Vercel-Deployment einen Einfluss auf SEO?
Indirekt, positiv. Vercel's Edge Network liefert statische Assets aus geografisch nahen CDN-Knoten, TTFB für statische Routes typischerweise unter 50ms. Das verbessert Core Web Vitals (TTFB, LCP) spürbar. Vercel-specific: Deploy Previews bekommen automatisch X-Robots-Tag: noindex, sind also nicht indexierbar. Preview-URLs landen nicht in Googles Index. Nur Production-Deployments werden indexiert.