SEO für Single-Page-Applications: Best Practices für 2026

Vadim Kravcenko
Vadim Kravcenko
· 6 min read

TL;DR: SEO für Single-Page-Applications beginnt mit einer unbequemen Wahrheit: SPAs machen es Suchmaschinen standardmäßig schwer. Google steckt JavaScript-Seiten zunächst in eine Rendering-Warteschlange — ein Prozess, der Stunden bis Tage dauern kann, und AI-Crawler wie GPTBot, ClaudeBot und PerplexityBot führen JavaScript überhaupt nicht aus. Die Lösung ist serverseitiges Rendering mit Next.js, Nuxt, Angular SSR oder SvelteKit. Dieser Leitfaden zeigt dir die genaue Einrichtung für jedes Framework — inklusive Code, Testschritten und der Rendering-Realität 2026.

Warum SPAs ein Problem sind

Single-Page-Applications laden ein einziges HTML-Grundgerüst und füllen es dann mit JavaScript. Für Nutzer fühlt sich das schnell und app-ähnlich an. Für Googlebot kommt oft erst einmal nur ein leeres <div id="app"></div> an.

Client-side vs server-side JavaScript rendering comparison using the hamburger analogy
Client-side vs server-side rendering — choosing the right approach for SEO. Source: Lumar
Diagram showing how client-side JavaScript rendering works in single-page applications
How client-side JavaScript rendering works — and why it causes SEO problems. Source: Lumar

Ich habe über SEOJuice Hunderte SPAs auditiert. Das Muster wiederholt sich ständig: Die Website sieht im Browser großartig aus, JavaScript läuft perfekt, und Suchmaschinen sehen nichts. Oder schlimmer — sie sehen den Inhalt erst Tage später, nachdem die Seite in Googles Rendering-Warteschlange gelegen hat. Allein der Angular-Hash-URL-Bug hat Kunden mehr organischen Traffic gekostet als jedes Algorithmus-Update, an das ich mich erinnern kann. Ein E-Commerce-Kunde mit Angular und HashLocationStrategy hatte 1.200 Produktseiten. Google sah exakt eine Seite — die Startseite. Alles nach dem # war unsichtbar. Das ist kein kleiner Ranking-Dämpfer. Das sind 60% des organischen Umsatzes, einfach weg, wegen einer Routing-Konfiguration, die man in zwei Minuten beheben kann, wenn man weiß, wonach man suchen muss.

So funktioniert Googles Rendering-Pipeline tatsächlich:

  1. Crawling — Googlebot ruft deine URL ab und erhält die rohe HTML-Antwort
  2. Warteschlange — Wenn die Seite JavaScript braucht, landet sie in einer Rendering-Warteschlange
  3. Rendering — Googles Web Rendering Service (eine Headless-Chromium-Instanz) führt JavaScript aus
  4. Indexierung — Das gerenderte HTML wird auf Inhalte und Links geparst

Diese Rendering-Warteschlange zwischen Schritt 2 und Schritt 3? Sie kann wenige Sekunden oder mehrere Tage dauern. Deine Wettbewerber mit serverseitig gerendertem HTML überspringen diese Warteschlange komplett — ihr Inhalt wird schon beim ersten Crawling indexiert.

Und es wird noch ungemütlicher. 2025 hat Vercel mehr als eine Milliarde Crawler-Requests analysiert und festgestellt, dass die meisten AI-Crawler JavaScript überhaupt nicht ausführen. GPTBot, ClaudeBot, PerplexityBot — sie konsumieren rohes, ungerendertes HTML. Eine Analyse von über einer halben Milliarde GPTBot-Abrufen fand keinerlei Hinweise auf JavaScript-Ausführung. Wenn deine SPA auf clientseitiges Rendering angewiesen ist, ist dein Inhalt für die Crawler unsichtbar, die hinter ChatGPT, Claude und der Suche von Perplexity stehen.

"Wenn deine Next.js-Website kritische Seiten als JavaScript-abhängige SPAs ausliefert, sind diese Seiten für die Systeme unzugänglich, die prägen, wie Menschen Informationen entdecken."

— Vercel Engineering Blog (Quelle)

Das ist kein Nischenproblem. Wenn du willst, dass dein Inhalt 2026 sowohl von Google als auch von AI-Suchmaschinen gefunden wird, ist serverseitiges Rendering nicht mehr optional — es ist Voraussetzung.

CSR vs SSR vs SSG vs ISR

Es gibt vier Wege, eine Single-Page-Application zu rendern. Diese Entscheidung bestimmt, ob Suchmaschinen deinen Inhalt sofort, irgendwann oder nie sehen.

AnsatzWie es funktioniertSEO-AuswirkungTime to First Byte (TTFB)Am besten geeignet für
CSR (Client-Side Rendering)Der Browser lädt ein leeres HTML-Grundgerüst herunter, JavaScript baut die SeiteSchlecht — Google steckt die Seite in die Rendering-Warteschlange, AI-Crawler sehen nichtsSchnell (aber leer)Interne Dashboards, Admin-Panels, geschützte Seiten
SSR (Server-Side Rendering)Der Server erzeugt pro Request vollständiges HTML und sendet die komplette SeiteExzellent — vollständiger Inhalt schon beim ersten CrawlingVariabel (Server-Verarbeitungszeit)Dynamische Inhalte: E-Commerce, News, nutzergenerierte Inhalte
SSG (Static Site Generation)Seiten werden beim Deploy als statisches HTML vorab gebautExzellent — schnellste Ladezeit, vollständig crawlbarAm schnellsten (über CDN ausgeliefert)Blogs, Dokumentation, Marketing-Seiten, Landingpages
ISR (Incremental Static Regeneration)Statische Seiten, die zeitgesteuert oder bei Bedarf neu generiert werdenExzellent — SSG-Geschwindigkeit mit frischem InhaltSchnell (gecacht mit Hintergrund-Rebuild)Große Websites mit periodisch wechselnden Inhalten (Produktkataloge, Listings)

Kernaussage

Jede Seite, die bei Google oder in AI-Suchmaschinen ranken soll, muss serverseitig gerendert oder vorgerendert sein. CSR ist okay für geschützte Seiten und Dashboards. Für alles, was öffentlich ist, nutze SSR, SSG oder ISR.

Die Regel ist simpel: Wenn eine URL in der Suche ranken soll, muss sie bereits in der ersten Serverantwort vollständiges HTML ausliefern. Keine Ausnahmen. Kein „aber Google rendert doch inzwischen JavaScript“. Google tut das — manchmal, irgendwann, unzuverlässig, und AI-Crawler versuchen es nicht einmal. Ich habe diese Diskussion mit Frontend-Entwicklern öfter geführt, als ich zählen kann. Das Gespräch endet meistens, wenn ich ihnen ihre Seite im URL-Prüftool von Google zeige und sie dort eine leere Seite sehen, wo eigentlich ihr wunderschönes UI sein sollte.

React / Next.js

Normales React (Create React App, Vite mit React) ist nur CSR. Google hat damit Probleme. Next.js ist die Antwort — und seit der App Router in Next.js 13+ zum Standard geworden ist, ist Next.js aus SEO-Sicht deutlich besser geworden.

React Server Components — der Standard 2026

Mit dem App Router werden Komponenten standardmäßig auf dem Server gerendert. Du fügst 'use client' nur dann hinzu, wenn eine Komponente Browser-APIs oder Interaktivität braucht. Das bedeutet: Der Großteil deines Seiteninhalts wird als pures HTML ausgeliefert — ganz ohne JavaScript-Rendering.

// app/blog/[slug]/page.tsx — Server Component (default)
import { Metadata } from 'next'

// Dynamic metadata for each blog post
export async function generateMetadata({ params }): Promise<Metadata> {
  const post = await getPost(params.slug)
  return {
    title: post.title,
    description: post.excerpt,
    openGraph: {
      title: post.title,
      description: post.excerpt,
      type: 'article',
      publishedTime: post.publishedAt,
    },
    alternates: {
      canonical: `https://example.com/blog/${params.slug}`,
    },
  }
}

// This component runs on the server — zero JS shipped to the browser
export default async function BlogPost({ params }) {
  const post = await getPost(params.slug)

  return (
    <article>
      <h1>{post.title}</h1>
      <div>{post.content}</div>
    </article>
  )
}

Statische Generierung mit generateStaticParams

Für Inhalte, die sich nicht häufig ändern (Blogposts, Landingpages), solltest du die Seiten schon beim Build vorab rendern:

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

// Combined with the page component above,
// Next.js generates static HTML at build time for every post

ISR für große Kataloge

Für E-Commerce-Seiten mit Tausenden Produkten nutzt du ISR, um Seiten nach Zeitplan neu zu validieren:

// app/products/[id]/page.tsx
export const revalidate = 3600 // Regenerate every hour

export default async function ProductPage({ params }) {
  const product = await getProduct(params.id)
  return <ProductDetail product={product} />
}

Wenn du in normalem React festhängst und nicht auf Next.js migrieren kannst, nutze als Zwischenlösung einen Pre-Rendering-Service wie Prerender.io. Aber mach dir nichts vor: Das ist Klebeband, keine echte Lösung. Jeder Monat, in dem du die Migration verschiebst, ist ein Monat mit suboptimaler Indexierung.

Vue / Nuxt 3

Gleiche Geschichte, anderes Ökosystem. Normales Vue mit Vue Router ist nur CSR. Nuxt 3 gibt dir SSR, SSG, ISR und Edge Rendering mit Nitro — alles in einem Framework.

Universal Rendering (SSR standardmäßig)

Nuxt 3 nutzt Universal Rendering direkt out of the box. Keine Konfiguration nötig — deine Seiten werden beim ersten Laden serverseitig gerendert und danach für clientseitige Navigation hydratisiert.

<!-- pages/blog/[slug].vue -->
<script setup>
const route = useRoute()
const { data: post } = await useFetch(`/api/posts/${route.params.slug}`)

// Per-page SEO metadata
useHead({
  title: post.value.title,
  meta: [
    { name: 'description', content: post.value.excerpt },
    { property: 'og:title', content: post.value.title },
    { property: 'og:description', content: post.value.excerpt },
  ],
  link: [
    { rel: 'canonical', href: `https://example.com/blog/${route.params.slug}` }
  ]
})
</script>

<template>
  <article>
    <h1>{{ post.title }}</h1>
    <div v-html="post.content" />
  </article>
</template>

Hybrid Rendering — unterschiedliche Strategien pro Route

Mit routeRules in Nuxt 3 kannst du Rendering-Strategien innerhalb derselben App mischen. Das ist extrem nützlich für Websites mit statischen Marketing-Seiten und dynamischen Inhalten:

// nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    '/':          { prerender: true },           // SSG — homepage
    '/blog/**':   { isr: 3600 },                 // ISR — blog posts regenerate hourly
    '/products/**': { ssr: true },               // SSR — dynamic product pages
    '/dashboard/**': { ssr: false },             // CSR — authenticated dashboard
  }
})

Edge Rendering mit Nitro

Nitro, die Server-Engine von Nuxt 3, unterstützt Deployments auf Edge-Plattformen (Cloudflare Workers, Vercel Edge, Netlify Edge). Das bedeutet: Deine SSR-Seiten werden an CDN-Edge-Standorten gerendert, die dem Nutzer am nächsten sind — sub-50ms TTFB sind realistisch. Für SEO heißt das: schnellere Ladezeiten, bessere Core Web Vitals und häufigeres Crawling durch Google.

Angular SSR

Angular war historisch eines der schwierigsten Frameworks, wenn es um SEO ging. Das hat sich seit Angular 17 deutlich geändert, weil SSR dort mit eingebauter Hydration-Unterstützung zum First-Class Citizen geworden ist. Kein nachträgliches Dranschrauben von Angular Universal mehr.

SSR in Angular 17+ einrichten

Neue Projekte bekommen SSR standardmäßig, wenn du die CLI verwendest:

# New project with SSR enabled
ng new my-app --ssr

# Add SSR to an existing project
ng add @angular/ssr

Dynamische Meta-Tags mit Angular-Services

// product-page.component.ts
import { Component, OnInit } from '@angular/core';
import { Meta, Title } from '@angular/platform-browser';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-product-page',
  template: `
    <article>
      <h1>{{ product.name }}</h1>
      <p>{{ product.description }}</p>
    </article>
  `
})
export class ProductPageComponent implements OnInit {
  product: any;

  constructor(
    private meta: Meta,
    private title: Title,
    private route: ActivatedRoute,
    private productService: ProductService
  ) {}

  ngOnInit() {
    const id = this.route.snapshot.paramMap.get('id');
    this.productService.getProduct(id).subscribe(product => {
      this.product = product;
      this.title.setTitle(product.name);
      this.meta.updateTag({ name: 'description', content: product.description });
      this.meta.updateTag({ property: 'og:title', content: product.name });
    });
  }
}

Incremental Hydration (Angular 19+)

Angular 19.2 hat Incremental Hydration eingeführt, aufbauend auf der @defer-API. Komponenten rendern vollständiges HTML auf dem Server, werden aber erst im Client hydratisiert, wenn ein Trigger ausgelöst wird (im Viewport, bei Interaktion usw.). Das reduziert das JavaScript, das an den Browser ausgeliefert wird, während für Crawler weiterhin vollständiger SSR-Inhalt verfügbar bleibt.

Angular-spezifischer Stolperstein

Hash-basiertes Routing (HashLocationStrategy) erzeugt URLs wie example.com/#/products. Google ignoriert alles nach dem #. Dein 500-Seiten-Produktkatalog sieht aus wie eine einzige Seite. Wechsle sofort zu PathLocationStrategy — das ist in Angular standardmäßig aktiv, aber einige Legacy-Projekte nutzen immer noch Hash-Routing. Genau dieser Bug hat den E-Commerce-Kunden von oben 60% seines organischen Traffics gekostet. Sie liefen zwei Jahre lang mit Hash-Routing. Zwei Jahre Produktseiten, von denen Google nie wusste, dass sie existieren. Der Fix dauerte 20 Minuten. Die Erholung dauerte vier Monate.

SvelteKit

SvelteKit hat sich still und leise zu einem der besten Frameworks für SEO out of the box entwickelt. SSR ist standardmäßig aktiviert — du müsstest es aktiv abschalten. Das Framework kompiliert sich praktisch selbst weg und liefert deutlich weniger JavaScript aus als React oder Angular.

SSR standardmäßig — keine Konfiguration nötig

Jede SvelteKit-Seite wird standardmäßig serverseitig gerendert. Deine +page.svelte-Dateien erzeugen beim ersten Request vollständiges HTML:

<!-- src/routes/blog/[slug]/+page.svelte -->
<script>
  export let data;
</script>

<svelte:head>
  <title>{data.post.title}</title>
  <meta name="description" content={data.post.excerpt} />
  <link rel="canonical" href={`https://example.com/blog/${data.post.slug}`} />
</svelte:head>

<article>
  <h1>{data.post.title}</h1>
  {@html data.post.content}
</article>
// src/routes/blog/[slug]/+page.server.ts
export async function load({ params }) {
  const post = await getPost(params.slug);
  return { post };
}

Hybrid Rendering pro Route

Wie Nuxt erlaubt dir auch SvelteKit, das Rendering pro Route zu steuern:

// src/routes/blog/[slug]/+page.ts
export const prerender = true;  // SSG — generate at build time

// src/routes/dashboard/+page.ts
export const ssr = false;       // CSR-only for authenticated content

Warum SvelteKit für SEO Aufmerksamkeit verdient: Der Compiler eliminiert die Framework-Runtime. Eine SvelteKit-Seite liefert nur einen Bruchteil des JavaScript aus, das eine vergleichbare Next.js- oder Nuxt-Seite braucht. Weniger JavaScript bedeutet schnelleres LCP, bessere INP-Werte und glücklichere Core Web Vitals — alles Ranking-Signale.

Die Checkliste

Jede SPA sollte diese Checks bestehen. Nach Wirkung sortiert — behebe zuerst die Punkte ganz oben.

#CheckWarum das wichtig istSo behebst du es
1SSR oder SSG für alle öffentlichen Seiten aktiviertOhne das steckt Google deine Seiten in die Rendering-Warteschlange und AI-Crawler sehen nichtsNext.js App Router, Nuxt 3, Angular SSR oder SvelteKit
2Saubere URLs (keine Hash-Fragmente)Hash-URLs (#/page) sind für Suchmaschinen unsichtbarNutze history-basiertes Routing — Standard in allen modernen Frameworks
3Eindeutiger Title-Tag pro SeiteDer gleiche Title auf jeder Route führt dazu, dass Google eine Version auswählt und den Rest ignoriertgenerateMetadata (Next.js), useHead() (Nuxt), Meta-Service (Angular), <svelte:head>
4Eindeutige Meta Description pro SeiteSteuert dein Snippet in den SuchergebnissenDieselben Libraries wie für Title-Tags — pro Route setzen
5Canonical-Tags auf jeder SeiteVerhindert Duplicate-Content-Probleme durch Query-Parameter und Trailing SlashesFüge pro Seite <link rel="canonical"> in deine Metadaten ein
6Saubere Heading-Hierarchie (H1 > H2 > H3)Signalisiert Crawlern die InhaltsstrukturEine H1 pro Seite, logische Verschachtelung in Komponenten
7Interne Links nutzen echte <a href>-TagsNur JavaScript-Navigation (onClick-Handler) blockiert CrawlerNutze Framework-Link-Komponenten: <Link>, <NuxtLink>, routerLink
8XML-Sitemap eingereichtHilft Google, Seiten zu entdecken, die nicht über Links erreichbar sindGeneriere sie mit next-sitemap, nuxt-simple-sitemap oder Framework-spezifischen Tools
9Code Splitting und Lazy LoadingReduziert das initiale JS-Bundle, verbessert LCP und INPDynamische Imports (next/dynamic, defineAsyncComponent, @defer)
10Schema Markup (JSON-LD) auf wichtigen SeitenErmöglicht Rich Snippets und hilft AI-Crawlern, Inhalte zu verstehenJSON-LD in <head> oder <body> — serverseitig gerendert, nicht per JS injiziert

Häufige SPA-SEO-Fehler — mit Code-Beispielen

Das sind die Fehler, die ich in fast jedem SPA-Audit sehe. Jeder einzelne davon zerstört Rankings.

Fehler 1: Sich bei öffentlichen Seiten auf CSR verlassen

„Aber Google rendert doch JavaScript!“ — ja, manchmal, irgendwann, wenn dein JS keinen Fehler wirft, wenn die Rendering-Warteschlange nicht überlastet ist, wenn dein JavaScript nicht ins Timeout läuft und wenn keine Third-Party-Skripte das Rendering stören. Das sind ziemlich viele Wenns, auf die du deinen organischen Traffic wetten würdest. Und AI-Crawler versuchen es nicht einmal.

// WRONG — CSR-only React app
// Google sees: <div id="root"></div>
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(<App />);

// RIGHT — Next.js Server Component
// Google sees: fully rendered HTML with all content
export default async function Page() {
  const data = await fetchData();
  return <Article data={data} />;
}

Fehler 2: Hash-basiertes Routing

Angulars HashLocationStrategy und der Hash-Modus von Vue Router erzeugen URLs wie example.com/#/products/shoes. Google ignoriert alles nach dem #. Deine komplette Anwendung sieht aus wie eine einzige Seite.

// WRONG — Vue Router hash mode
const router = createRouter({
  history: createWebHashHistory(),  // URLs: example.com/#/about
  routes
})

// RIGHT — Vue Router history mode
const router = createRouter({
  history: createWebHistory(),      // URLs: example.com/about
  routes
})

Fehler 3: Derselbe Title-Tag auf jeder Seite

SPAs werden mit einem einzigen <title> in der HTML-Hülle ausgeliefert. Wenn du ihn nicht pro Route dynamisch aktualisierst, hat jede Seite denselben Title. Google indexiert dann eine Version und ignoriert den Rest.

<!-- WRONG — static HTML shell with one title -->
<!DOCTYPE html>
<html>
  <head>
    <title>My App</title>  <!-- Same for every route -->
  </head>
  <body><div id="app"></div></body>
</html>

<!-- RIGHT — dynamic metadata per route (Nuxt example) -->
<script setup>
useHead({
  title: `${product.name} | MyStore`,
  meta: [{ name: 'description', content: product.summary }]
})
</script>

Fehler 4: JavaScript-Fehler blockieren das Rendering

Ein einziger ungefangener Fehler in deiner Anwendung kann verhindern, dass die gesamte Seite gerendert wird. Googles Web Rendering Service versucht es nicht erneut. Die Seite bleibt leer im Index.

Ich sehe das ständig: Ein Third-Party-Analytics-Skript wirft einen Fehler, oder eine fehlende API-Response crasht den Component Tree. Das Ergebnis? Google indexiert eine leere Seite. Ein Kunde hatte ein Hotjar-Snippet, das im Renderer von Google gelegentlich fehlschlug. Ihre Produktseiten wurden im URL-Prüftool der GSC zufällig als leer angezeigt. Die Lösung war eine Error Boundary rund um die Analytics-Initialisierung. Hat 10 Minuten gedauert. Hat ihre Indexierung aber monatelang still beschädigt.

Fix: Füge Error Boundaries in React hinzu (ErrorBoundary-Komponenten), nutze NuxtErrorBoundary in Nuxt und teste immer mit deaktiviertem JavaScript (mehr dazu gleich).

Fehler 5: Keine Sitemap

SPAs mit clientseitigem Routing legen ihre URL-Struktur nicht über HTML-Links offen, wie klassische Multi-Page-Websites das tun. Ohne Sitemap entdeckt Google Seiten nur über crawlbare Links — und wenn dein internes Linking JavaScript-gesteuert ist, findet Google womöglich gar nichts.

# Install next-sitemap for Next.js
npm install next-sitemap

# next-sitemap.config.js
module.exports = {
  siteUrl: 'https://example.com',
  generateRobotsTxt: true,
  changefreq: 'weekly',
  // Exclude routes that shouldn't be indexed
  exclude: ['/dashboard/*', '/api/*', '/admin/*'],
}

Fehler 6: JavaScript in robots.txt blockieren

Wenn deine robots.txt CSS- oder JS-Dateien blockiert, kann Googles Renderer deine Seite nicht aufbauen. Das sehen wir überraschend oft — meistens als übrig gebliebene Standardkonfiguration.

# WRONG — blocking JS and CSS
User-agent: *
Disallow: /static/js/
Disallow: /static/css/

# RIGHT — allow all resources needed for rendering
User-agent: *
Disallow: /api/
Disallow: /dashboard/
Allow: /static/

SEO für Single-Page-Applications testen — Schritt für Schritt

Google-Lighthouse-Performance-Audit-Bericht mit Scores für Performance, Barrierefreiheit, Best Practices und SEO
Ein Lighthouse-Performance-Audit-Bericht. JavaScript-lastige SPAs schneiden bei Performance-Metriken wegen des Overheads durch clientseitiges Rendering oft schlechter ab. Quelle: Shopify

Geh nicht davon aus, dass deine SPA crawlbar ist, nur weil sie in Chrome funktioniert. So prüfst du, was Suchmaschinen tatsächlich sehen.

Test 1: URL-Prüfung in der Google Search Console

Das URL-Prüftool ist dein bestes einzelnes Diagnosewerkzeug. Gib irgendeine URL ein und klicke auf „Live-URL testen“. Google ruft deine Seite ab, rendert sie mit seinem Web Rendering Service und zeigt dir das Ergebnis.

Worauf du achten solltest:

  • Screenshot-Tab — Zeigt er deinen tatsächlichen Inhalt oder eine leere Seite / einen Loading-Spinner?
  • Tab „Gerendertes HTML“ — Ist dein Inhalt im DOM? Suche nach wichtigen Textstellen.
  • Tab „Weitere Informationen“ — Prüfe auf JavaScript-Console-Fehler. Ungefangene Fehler können bedeuten, dass das Rendering fehlgeschlagen ist.
  • Seitenressourcen — Verifiziere, dass keine kritischen JS-/CSS-Dateien blockiert sind oder Fehler zurückgeben.

Test 2: JavaScript im Browser deaktivieren

Das ist mein Lieblings-Test, weil er brutal ehrlich ist. Deaktiviere JavaScript in Chrome DevTools oder nutze eine Browser-Erweiterung und lade die Seite neu. Wenn du dann keinen Hauptinhalt, keine Navigation oder keine internen Links mehr siehst, hast du ein SEO-Problem. Nicht jede Seite muss ohne JavaScript perfekt interaktiv sein — aber die Inhalte, die ranken sollen, müssen sichtbar sein.

Test 3: HTML-Antwort mit curl prüfen

Ruf die URL direkt per curl ab und schau dir an, was in der ersten Serverantwort steckt. Wenn dort nur ein App-Grundgerüst und Script-Tags stehen, aber kein eigentlicher Seiteninhalt, lieferst du keine suchmaschinenfreundliche HTML-Antwort aus.

curl -A "Googlebot" -L https://example.com/product/widget-123
curl -A "GPTBot" -L https://example.com/product/widget-123

Vergleiche die Antworten. Im Idealfall sehen beide Bots denselben vollständigen HTML-Inhalt. Wenn GPTBot praktisch nichts außer einem Grundgerüst bekommt, weißt du sofort, warum du in AI-Suchergebnissen nicht auftauchst.

Test 4: Führe ein vollständiges SEO-Audit durch

Unser kostenloses SEO-Audit-Tool scannt deine SPA auf Rendering-Probleme, fehlende Meta-Tags, defekte Links und Accessibility-Probleme. Es zeigt dir exakt, was Suchmaschinen sehen — kein Login nötig, Ergebnisse in 30 Sekunden.

Test 5: Zugriff für AI-Crawler prüfen

Da AI-Crawler kein JavaScript rendern, solltest du mit dem AI Crawler Inspector prüfen, ob sie auf deinen Inhalt zugreifen können. Das Tool simuliert, wie GPTBot, ClaudeBot und andere AI-Bots deine Seiten sehen.

SPA-SEO im Jahr 2026: Was sich verändert hat

Die SPA-SEO-Landschaft sieht 2026 spürbar anders aus als noch vor zwei Jahren. Das ist es, worauf es jetzt ankommt.

React Server Components sind der neue Standard

Mit dem Next.js App Router werden Komponenten standardmäßig auf dem Server gerendert. Mit 'use client' entscheidest du dich explizit für clientseitiges Rendering. Das kehrt das alte Modell um — statt dass alles CSR ist und SSR irgendwie drangeschraubt wird, ist alles SSR und CSR wird nur dort ergänzt, wo es nötig ist. Die SEO-Auswirkungen sind erheblich: Der Großteil deiner Anwendung wird automatisch als pures HTML ausgeliefert.

Edge Rendering ist produktionsreif

Nuxt 3 mit Nitro, Next.js Edge Runtime und SvelteKit-Adapter deployen SSR inzwischen an CDN-Edge-Standorte (Cloudflare Workers, Vercel Edge Functions). Deine Seiten werden am Edge-Knoten gerendert, der dem Nutzer — oder Crawler — am nächsten ist. Sub-50ms TTFB sind global erreichbar.

Angular hat endlich First-Class-SSR

Angular 17+ hat SSR mit ng new --ssr direkt in die CLI integriert. Angular 19 hat Incremental Hydration ergänzt. Die Zeiten schmerzhafter Angular-Universal-Setups sind vorbei. Wenn du immer noch eine reine CSR-Angular-App betreibst, ist der Migrationspfad heute ziemlich geradlinig.

AI-Crawler sind ein echter SEO-Kanal

GPTBot, ClaudeBot, PerplexityBot und andere crawlen das Web, um Trainingsdaten aufzubauen und AI-Suche zu betreiben. Keiner von ihnen führt JavaScript aus. Die Analyse von über einer halben Milliarde GPTBot-Requests fand keinerlei Hinweise auf JS-Ausführung. Wenn du willst, dass dein Inhalt in AI-generierten Antworten zitiert wird, ist SSR die einzige Option.

"Gerendertes HTML zu sehen und nicht nur den Source Code ist wichtig, um zu diagnostizieren, ob es ein Indexierungsproblem gibt. Google kann deine Links nur entdecken, wenn sie <a>-HTML-Elemente mit einem href-Attribut sind."

— Martin Splitt, Developer Advocate bei Google (Quelle)

Core Web Vitals sind weiterhin wichtig

LCP, INP und CLS bleiben Ranking-Signale. SPAs mit großen JavaScript-Bundles werden bei LCP (die Seite braucht zu lange, um sinnvollen Inhalt anzuzeigen) und INP (Interaktionen fühlen sich träge an) abgestraft. Code Splitting, Lazy Loading und minimales clientseitiges JavaScript sind nicht optional — sie sind Performance-Anforderungen mit direktem Einfluss auf Rankings.

"Deine Website statisch oder auf dem Server vorzugenerieren ist die Best Practice für SEO — es macht Crawler eher bereit, deine Website häufiger neu zu indexieren."

— Vercel Engineering Blog (Quelle)

Schneller Framework-Vergleich

Nicht sicher, welches Framework du wählen sollst? So schneiden sie speziell in Sachen SEO ab.

FeatureNext.js (React)Nuxt 3 (Vue)Angular SSRSvelteKit
SSR standardmäßigJa (App Router)JaJa (seit v17)Ja
Statische GenerierunggenerateStaticParamsprerender: trueng build --prerenderexport const prerender = true
ISR-UnterstützungIntegriert (revalidate)Integriert (isr: seconds)Manuell über Service WorkerÜber adapter-spezifische Konfiguration
Edge RenderingVercel Edge, CloudflareNitro (plattformübergreifend)BegrenztMehrere Adapter
Metadata-API pro SeitegenerateMetadatauseHead()Meta- + Title-Services<svelte:head>
Ausgeliefertes Client-JSMittel (RSC hilft)MittelSchwerMinimal (wegkompiliert)
Community/ÖkosystemAm größtenStarkEnterprise-fokussiertWächst schnell

Häufig gestellte Fragen

Kann Google Single-Page-Applications crawlen?

Ja, aber mit Einschränkungen. Googles Web Rendering Service nutzt einen Headless-Chromium-Browser, um JavaScript auszuführen und SPAs zu rendern. Dieses Rendering passiert jedoch in einer separaten Rendering-Warteschlange nach dem ersten Crawling, was die Indexierung um Stunden bis Tage verzögern kann. Seiten mit JavaScript-Fehlern werden möglicherweise nie gerendert. Für zuverlässige Indexierung solltest du SSR oder SSG verwenden — verlass dich bei zeitkritischen Inhalten nicht auf Googles Rendering-Warteschlange.

Ist eine Single-Page-Application schlecht für SEO?

Eine reine CSR-SPA ist schlecht für SEO. Eine SPA mit serverseitigem Rendering ist es nicht. Das Framework ist nicht entscheidend — entscheidend ist, ob die erste HTML-Antwort deinen Inhalt enthält. Next.js, Nuxt, Angular SSR und SvelteKit erzeugen alle vollständig crawlbare SPAs. Das „SPA vs. SEO“-Problem wurde vor Jahren gelöst; das eigentliche Problem sind Entwickler, die die Lösung nicht umsetzen.

Brauche ich serverseitiges Rendering für eine React-App?

Für jede Seite, die in der Suche ranken soll? Ja. React allein (über Vite oder Create React App) ist nur CSR — Suchmaschinen sehen eine leere Seite. Next.js ergänzt SSR, SSG und ISR. Mit React Server Components im App Router werden die meisten Komponenten standardmäßig auf dem Server gerendert. Wenn deine React-App öffentliche Inhalte ausliefert, ist Next.js die Standardlösung.

Wie gehen AI-Suchmaschinen mit SPAs um?

Gar nicht. GPTBot (OpenAI), ClaudeBot (Anthropic), PerplexityBot und andere AI-Crawler führen kein JavaScript aus. Sie parsen nur rohes HTML. Die Analyse von über einer halben Milliarde GPTBot-Requests fand keinerlei Hinweise auf JavaScript-Rendering. Wenn dein Inhalt clientseitig gerendert wird, ist er für AI-Suchmaschinen unsichtbar. SSR ist der einzige Weg, in AI-generierten Antworten und Zitaten aufzutauchen.

Was ist der Unterschied zwischen SSR, SSG und ISR?

SSR (Server-Side Rendering) erzeugt HTML bei jedem Request — ideal für dynamische Inhalte. SSG (Static Site Generation) erzeugt HTML beim Build — am schnellsten, aber bei Inhaltsänderungen sind Rebuilds nötig. ISR (Incremental Static Regeneration) erzeugt statische Seiten, die sich nach Zeitplan automatisch neu generieren — kombiniert SSG-Geschwindigkeit mit frischem Inhalt. Alle drei liefern Suchmaschinen beim ersten Request vollständiges HTML. Die Wahl hängt davon ab, wie oft sich dein Inhalt ändert.

Fazit

SPAs sind nicht grundsätzlich schlecht für SEO. Aber reine CSR-SPAs sind es — und 2026 sind sie auch für AI-Suchmaschinen unsichtbar.

Die Lösung gibt es seit Jahren. Next.js, Nuxt 3, Angular SSR und SvelteKit liefern serverseitig gerendertes HTML direkt mit. React Server Components haben den Standard sogar noch verbessert — der Großteil deiner App wird automatisch auf dem Server gerendert. Es gibt keinen guten Grund mehr, eine öffentliche SPA ohne serverseitiges Rendering auszuliefern.

Wenn du unsicher bist, ob deine SPA crawlbar ist, starte ein kostenloses Audit — es dauert 30 Sekunden und zeigt dir exakt, was Google sieht. Für die Sichtbarkeit bei AI-Crawlern prüfe den AI Crawler Inspector.

Passende weiterführende Artikel:

SEOJuice
Stay visible everywhere
Get discovered across Google and AI platforms with research-based optimizations.
Works with any CMS
Automated Internal Links
On-Page SEO Optimizations
Get Started Free

no credit card required