JavaScript-SEO: Wie Google SPAs und React-Websites indexiert
Die zweistufige Rendering-Warteschlange von Google, die Fallstricke von CSR, der Unterschied zwischen SSR, SSG und ISR und praktische Methoden, mit denen Sie prüfen, ob Ihre JavaScript-Website korrekt indexiert wird.
Wie Google JavaScript rendert: so funktioniert es
Bei einer normalen HTML-Seite nimmt Google nur einen Schritt: Es lädt das HTML und sieht den Inhalt sofort. Bei einer JavaScript-Seite sind es drei Schritte: HTML herunterladen → JS-Bundle laden → im Headless Chromium ausführen, um das finale DOM zu erhalten.
Google nutzt eine eigene, auf Chromium basierende Browser-Engine, die regelmäßig aktualisiert wird. Moderne JavaScript-Funktionen (ES2020+, dynamische Imports, WebAssembly) versteht deshalb der Googlebot. Das Problem ist nicht die Unterstützung der Syntax, sondern die Verzögerung beim Rendering und die Ressourcenbeschränkungen beim Crawling.
Rendering in Zahlen
Rendering-Timeout
Führt Google das JavaScript nicht innerhalb von etwa 3–4 Sekunden aus, indexiert es nur eine teilweise gerenderte Seite
CSS-Ladezeit
Ressourcen, deren Laden länger als 150 ms dauert, können das Rendering blockieren und die Effizienz des Crawlings senken
Indexierung
JavaScript-Inhalte gelangen verzögert in den Index, verglichen mit HTML-Inhalten: manchmal erst nach Tagen oder Wochen
Evergreen-Google
Der Googlebot aktualisiert sich auf das aktuelle stabile Chromium. Moderne JavaScript-Funktionen werden vollständig unterstützt
Zweistufige Indexierung: warum JavaScript-Inhalte später im Index landen
Google teilt das Crawling in zwei Stufen. Die erste Welle ist das Crawling: Der Googlebot lädt das HTML und alle gefundenen Links herunter. Die zweite Welle ist das Rendering: Der Bot reiht die Seiten zum Rendering ein, führt das JavaScript aus und indexiert das finale DOM.
Zwischen den beiden Wellen können Stunden bis Wochen vergehen. Das hängt von der Autorität der Website, vom Crawl-Budget und von der Größe der Rendering-Warteschlange bei Google ab. Werden wichtige Texte, H1-Überschriften, Meta-Tags oder Links nur per JavaScript erzeugt, erreichen sie den Index mit Verzögerung.
CSR: die größte SEO-Falle
Beim Client-Side Rendering (CSR) liefert der Server ein leeres <div id="root"></div> aus. Das gesamte HTML entsteht erst im Browser, nachdem das JavaScript-Bundle geladen wurde. React, Vue und Angular arbeiten im SPA-Modus standardmäßig so.
Aus SEO-Sicht ist CSR aus mehreren Gründen ein Problem: 1) Das Rendering findet erst in der zweiten Welle statt. 2) Ressourcen, die der Crawler nicht laden kann (Drittanbieter-Skripte, CDNs mit Sperren in der robots.txt), fehlen, und die Seite wird unvollständig gerendert. 3) Jeder JavaScript-Fehler führt zu einer leeren Seite im Index.
<!-- CSR: what Google sees in the first wave -->
<html>
<head>
<title></title> <!-- empty -->
</head>
<body>
<div id="root"></div> <!-- no content -->
<script src="/bundle.js"></script>
</body>
</html><title>, <meta name="description"> und <h1> nur per clientseitigem JavaScript erzeugen, erhält Google beim ersten Crawling leere oder Standardwerte. Die Seite landet dann ohne diese Angaben im Index.SSR, SSG und ISR: was Sie für SEO wählen sollten
Die Lösung für die Probleme mit CSR ist die serverseitige Erzeugung des HTML. Dafür gibt es drei Hauptansätze, die jeweils für ein bestimmtes Szenario optimal sind.
Vergleich der Rendering-Ansätze
| Ansatz | HTML auf dem Server | SEO | Dynamische Daten |
|---|---|---|---|
| CSR | Nein | Schwach | Vollständig |
| SSR | Ja (bei jeder Anfrage) | Sehr gut | Hoch |
| SSG | Ja (beim Build) | Sehr gut | Nein (Neuaufbau nötig) |
| ISR | Ja (zeitgesteuert) | Sehr gut | Über Revalidierung |
| Ansatz | Geeignet für |
|---|---|
| CSR | Authentifizierte SPAs, Dashboards |
| SSR | Personalisierte Seiten, Kataloge |
| SSG | Blog, Landingpages, Dokumentationen |
| ISR | Preiskataloge, Nachrichten |
SSR (Server-Side Rendering): Das HTML entsteht bei jeder Anfrage auf dem Server. Die Daten sind maximal aktuell, die Serverlast ist aber höher. In Next.js liefern generateMetadata und async-Komponenten im App Router standardmäßig SSR.
SSG (Static Site Generation): Das HTML wird einmal beim Build erzeugt und als statische Datei ausgeliefert. Die Zeit bis zum ersten Byte (TTFB) ist dabei am kürzesten, ideal für SEO. Nachteil: Bei Datenänderungen ist ein Neuaufbau nötig.
ISR (Incremental Static Regeneration): eine Mischform. Seiten werden statisch gebaut, nach Ablauf eines Revalidierungszeitraums (revalidate: 3600) erzeugt der Server sie bei der nächsten Anfrage aber im Hintergrund neu. In Next.js ist das der Standardansatz für die meisten Seiten.
// Next.js App Router — SSG + ISR
export const revalidate = 3600; // revalidate every hour
export async function generateMetadata(): Promise<Metadata> {
return {
title: 'Product Catalogue',
description: 'Full range with up-to-date prices',
};
}
// All critical content is server-rendered:
export default async function CatalogPage() {
const products = await fetchProducts(); // server fetch
return (
<main>
<h1>Product Catalogue</h1>
{products.map(p => <ProductCard key={p.id} {...p} />)}
</main>
);
}Dynamische Links und Navigation
Der Googlebot erkennt nur Links im Format <a href="/url">. Links, die über onClick, button, data-href oder window.location umgesetzt sind, bleiben für den Crawler unsichtbar. Seiten, die nur über solche Navigation erreichbar sind, werden deshalb möglicherweise nicht indexiert.
- Verwenden Sie
<a href>für alle Navigationslinks, nichtbutton onClickmitrouter.push() - Paginierung über URL-Parameter (
?page=2): Der Googlebot crawlt solche URLs, wenn sie im HTML vorkommen - SPA-Router: Next.js
<Link>und React Router<Link>erzeugen auf dem Server saubere<a>-Tags - Hash-Navigation (
#anchor) erzeugt im Index keine eigenen URLs. Nutzen Sie sie nicht für Inhalte, die eigenständig ranken sollen - Dynamische Menüs: Werden Menüpunkte nach dem Laden der Seite über eine API eingeblendet, entdeckt Google sie unter Umständen erst beim Rendering
Lazy Loading und Endlos-Scroll
Bilder mit loading="lazy" lädt der Googlebot mit, denn der moderne Crawler unterstützt Lazy Loading. Eine Bedingung gibt es aber: Das Bild muss beim SSR mit einem korrekten src-Attribut im DOM stehen. Setzt erst der Browser das src per JavaScript, sieht der Crawler ein leeres Tag.
Endlos-Scroll braucht einen crawlbaren Pfad zu jedem sinnvollen Eintrag. Stellen Sie fortlaufende URLs und gewöhnliche Links bereit, die auch ohne Klick auf eine Schaltfläche funktionieren. Prüfen Sie danach mit der URL-Prüfung oder einem Crawl, ob das HTML nach dem Rendering die beabsichtigten Inhalte zeigt.
| Muster | Sieht der Googlebot es? | Empfehlung |
|---|---|---|
| <img src="/img.webp" loading="lazy"> | Ja | Verwenden |
| <img data-src="/img.webp"> (JS setzt src) | Nein | Vermeiden |
| Endlos-Scroll ohne URL | Nur der erste Bildschirm | Paginierung ergänzen |
| Inhalt hinter der Schaltfläche „Mehr anzeigen“ | Nein | Einen Teil im HTML ausgeben |
| Tab-Inhalte (versteckte Tabs) | Ja, aber verzögert | Im HTML duplizieren |
Diagnose: so prüfen Sie das JavaScript-Rendering
Die zentrale Frage lautet: „Was sieht der Googlebot auf meiner Seite?“ Mehrere Werkzeuge helfen bei der Antwort.
Diagnose-Werkzeuge
- Google Search Console → URL-Prüfung: zeigt einen Screenshot der Seite nach dem Rendering durch den Googlebot sowie eine Liste der Ressourcen und gefundenen Links. Das ist die direkteste Prüfmethode.
- „Als Googlebot anzeigen“ in der GSC: startet den echten Crawler und liefert das HTML nach dem Rendering. Vergleichen Sie es mit dem Quell-HTML.
curloderwget: Rufen Sie das rohe HTML ohne JavaScript ab. Stehen wichtige Meta-Tags und Inhalte in dercurl-Ausgabe, gelangen sie in die erste Indexierungswelle.- JavaScript in den Chrome-DevTools deaktivieren (F12 → Strg+Umschalt+P → „Disable JavaScript“): So sehen Sie die Seite schnell so, wie sie ein Crawler ohne Rendering sieht.
- Screaming Frog mit Rendering: Mit der Einstellung „Spider > Configuration > Rendering > Googlebot“ crawlen Sie die Website mit JavaScript-Rendering und sehen die Links, die erst nach dem Rendering gefunden werden.
# Check what Google sees without JS rendering:
curl -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" \
https://example.com/page
# Find all title / meta description / h1 in HTML response:
curl -s https://example.com/page | grep -E '<title>|<meta name="description"|<h1'JavaScript-SEO-Checkliste
Wichtige Prüfungen
- Title und Meta-Description stehen in der HTML-Antwort des Servers (SSR/SSG) und werden nicht per JavaScript erzeugt
- H1, H2 und der Haupttext sind ohne JavaScript zugänglich
- Navigationslinks nutzen
<a href>, nichtonClickoderbutton - Strukturierte Daten (JSON-LD) stehen im
<head>der HTML-Antwort - Bilder haben ein statisches
srcim HTML.loading="lazy"setzen Sie nur bei Bildern ein, die nicht das LCP sind - robots.txt blockiert keine JavaScript- und CSS-Dateien, die fürs Rendering nötig sind
- Keine JavaScript-Fehler, die das Rendering stören (prüfen Sie die Konsole in den Chrome-DevTools auf der Seite)
- Core Web Vitals: LCP, INP und CLS erreichen die Schwellenwerte von Google
- Paginierung über URL-Parameter, nicht nur über den JavaScript-Zustand
- Kanonische URLs (
<link rel="[canonical](/glossary/canonical)">) stehen im HTML und werden nicht per JavaScript gesetzt
FAQ
Kann Google JavaScript überhaupt indexieren?
Wird eine React- oder Next.js-Website automatisch gut indexiert?
Brauche ich Prerendering oder dynamisches Rendering?
Kann ich React.lazy und Code-Splitting nutzen?
Wie prüfe ich, ob meine Website korrekt indexiert wird?
Check it with SpiderHead
Free and local: run the audit on your own machine.



