WHILE.CHAT·WORK · Tech & KI·13 MIN·Max Götte
Technical SEO: SPAs & Next.js sichtbar machen
work · Tech & KIJuni 202613 Min. LesezeitMax Götte

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 useTransition fü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 width und height auf <Image>

  • Fonts mit font-display: optional oder swap

  • 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_cache fü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

// 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.

projekt anfragen → WhatsApp mehr Artikel

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.