SSR vs SSG mit Claude Code: Rendering in Next.js und Astro wählen
Vergleiche SSR, SSG, ISR und Static Export in Next.js/Astro mit Claude Code, ausführbarem Code und Prüfkommandos.
Begriffe zuerst klären
Die Entscheidung zwischen SSR und SSG ist nicht nur eine Frage der Geschwindigkeit. SSR bedeutet server-side rendering: Der Server erzeugt HTML, sobald eine Anfrage eingeht. SSG bedeutet static site generation: HTML wird beim Build erzeugt und danach über CDN oder statisches Hosting ausgeliefert. ISR, Incremental Static Regeneration, liegt dazwischen: Die Seite wird statisch ausgeliefert und nach Zeitfenster oder Ereignis neu generiert.
Ein häufiger Fehler bei Next.js App Router ist die Annahme, dass ein Server Component automatisch SSR bei jeder Anfrage bedeutet. Das stimmt nicht. In der aktuellen Dokumentation zu Dynamic Route Segments werden TypeScript-params als Promise typisiert. Wenn Rendering ausdrücklich auf eine echte Anfrage warten soll, ist connection die aktuelle API.
Wenn du Claude Code nur bittest, eine Seite schneller zu machen, kann es zu viel statisch machen und Inventar, Suche oder Mitglieder-UI einfrieren. Wenn du alles auf SSR stellst, steigen TTFB und Serverkosten. Besser ist eine Routing-Matrix: Datenfrische, Personalisierung, Aktualisierungsfrequenz, Monetarisierungswirkung und Verifikationskommando pro Route.
Vergleich und Praxisfälle
| Frage | SSG | ISR | SSR |
|---|---|---|---|
| Wann entsteht HTML? | Beim Build | Beim Build und nach Revalidierung | Bei der Anfrage |
| Geeignet für | Artikel, Doku, Landingpages | Produkte, Kategorien, News | Dashboards, Suche, Warenkorb |
| Datenfrische | Build-Snapshot | Zeit- oder ereignisbasiert | Fast aktuell |
| Kosten | Niedrig | Mittel | Oft höher |
| Typischer Fehler | Lange Builds, alte Inhalte | Kurzzeitig alte Antwort | Langsam ohne Cache |
Praxisfall 1 ist ein Blog oder eine Dokumentation. Wenn Body, OGP, interne Links und CTA beim Veröffentlichen feststehen, ist SSG am saubersten. Bei Änderungen wird neu gebaut. Wenn zusätzlich JavaScript reduziert werden soll, passt Code Splitting mit Claude Code dazu.
Praxisfall 2 ist eine Produktseite. Preis, Verfügbarkeit und Kategoriesortierung können alle paar Minuten wechseln, aber die meisten Besucher brauchen eine schnelle Antwort. ISR passt dazu. Der offizielle Next.js ISR Guide nennt wichtige Grenzen: ISR läuft mit Node.js runtime und nicht mit Static Export.
Praxisfall 3 ist ein Konto-Dashboard. Cookies, Berechtigungen, Abostatus, Benachrichtigungen und private Empfehlungen hängen von der Anfrage ab. Behandle diese Route als SSR und setze Cache-Header bewusst. Wenn dein Team Edge-Rendering prüft, lies danach Edge Computing mit Claude Code.
Next.js SSR Beispiel
Dieses Beispiel kann in ein Next.js App Router Projekt kopiert werden. Es nutzt dummyjson.com und braucht keinen API-Schlüssel. connection() und cache: "no-store" machen das Anfrageverhalten im Review klar.
// app/products/[id]/page.tsx
import { notFound } from "next/navigation";
import { connection } from "next/server";
type Product = {
id: number;
title: string;
price: number;
stock: number;
updatedAt: string;
};
async function getProduct(id: string): Promise<Product | null> {
await connection();
const res = await fetch(`https://dummyjson.com/products/${id}`, {
cache: "no-store",
});
if (res.status === 404) return null;
if (!res.ok) throw new Error(`Failed to load product: ${res.status}`);
const data = (await res.json()) as {
id: number;
title: string;
price: number;
stock: number;
meta?: { updatedAt?: string };
};
return {
id: data.id,
title: data.title,
price: data.price,
stock: data.stock,
updatedAt: data.meta?.updatedAt ?? new Date().toISOString(),
};
}
export default async function ProductPage({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
const product = await getProduct(id);
if (!product) notFound();
return (
<main>
<h1>{product.title}</h1>
<p>Price: ${product.price.toLocaleString("en-US")}</p>
<p>Stock: {product.stock}</p>
<p>Updated: {new Date(product.updatedAt).toLocaleString("de-DE")}</p>
</main>
);
}
Der häufigste Stolperstein ist cookies() oder headers() in einem gemeinsamen Layout. Das wirkt harmlos, kann aber Routen dynamisch machen. Wenn dieses Layout Artikel umschließt, verlieren Seiten unnötig SSG. Lass Claude Code vor dem Patch auflisten, welche Routen dadurch betroffen sind.
SSG, ISR und Static Export trennen
SSG und ISR fühlen sich für Besucher beide statisch an, werden aber unterschiedlich betrieben. SSG wird beim Build erneuert. ISR wird nach Zeitfenster oder Ereignis erneuert. Static Export nutzt output: "export" und erzeugt einen out-Ordner, der ohne Node.js-Server ausgeliefert werden kann. Der offizielle Static Exports Guide erklärt, dass next build pro Route HTML-Dateien für statisches Hosting erzeugen kann.
// app/catalog/[id]/page.tsx
import { notFound } from "next/navigation";
export const revalidate = 3600;
type Product = {
id: number;
title: string;
description: string;
};
export async function generateStaticParams() {
return ["1", "2", "3"].map((id) => ({ id }));
}
async function getProduct(id: string): Promise<Product | null> {
const res = await fetch(`https://dummyjson.com/products/${id}`, {
next: { revalidate: 3600, tags: [`product:${id}`] },
});
if (res.status === 404) return null;
if (!res.ok) throw new Error(`Failed to load product: ${res.status}`);
return (await res.json()) as Product;
}
export default async function CatalogPage({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
const product = await getProduct(id);
if (!product) notFound();
return (
<article>
<h1>{product.title}</h1>
<p>{product.description}</p>
</article>
);
}
// next.config.mjs
const nextConfig = {
output: "export",
images: {
unoptimized: true,
},
};
export default nextConfig;
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"export:check": "next build && npx serve out"
}
}
Static Export und ISR sollten nicht vermischt werden. Static Export ist für statisches Hosting. Wenn Cookies, On-Demand-Revalidation, Server Functions oder echtes SSR gebraucht werden, ist ein Server-Runtime nötig. Teile Claude Code vor der Implementierung mit, ob das Ziel Cloudflare Pages statisch, ein Node-Container, Vercel, Netlify oder etwas anderes ist.
Astro statisch und on demand
Astro startet standardmäßig mit statischer Generierung. Die offizielle Dokumentation zu Astro on-demand rendering erklärt, dass Seiten, Routen und API-Endpunkte standardmäßig beim Build prerendered werden. Nach Installation eines Server-Adapters kann eine Route mit export const prerender = false auf Rendering zur Anfragezeit umgestellt werden.
---
// src/pages/docs/[slug].astro
export async function getStaticPaths() {
const docs = [
{ slug: "ssr", title: "SSR guide" },
{ slug: "ssg", title: "SSG guide" },
];
return docs.map((doc) => ({
params: { slug: doc.slug },
props: { doc },
}));
}
const { doc } = Astro.props;
---
<html lang="de">
<body>
<article>
<h1>{doc.title}</h1>
<p>This page was generated at build time.</p>
</article>
</body>
</html>
---
// src/pages/account.astro
export const prerender = false;
const session = Astro.cookies.get("session")?.value;
const name = session ? "Masa" : "Guest";
Astro.response.headers.set("Cache-Control", "private, no-store");
---
<html lang="de">
<body>
<h1>Account</h1>
<p>Hello, {name}.</p>
</body>
</html>
Bei Astro wird oft der Adapter vergessen. Lokal sieht die Seite korrekt aus, aber on-demand rendering benötigt in Produktion einen Server-Runtime. Lass Claude Code astro.config.mjs, Deployment-Plattform und jede prerender-Ausnahme prüfen.
Prüfkommandos und Claude-Code-Prompt
Die Rendering-Strategie lässt sich nicht nur durch Lesen des Codes bestätigen. Prüfe Build-Ausgabe, Response-Header, Cache-Logs und Performance-Werte. Der Next.js ISR Guide empfiehlt für Produktionsverhalten next build gefolgt von next start.
# Next.js: production behavior
npm run build
npm run start
# In another terminal
curl -I http://localhost:3000/catalog/1
curl -I http://localhost:3000/products/1
# ISR cache debugging
NEXT_PRIVATE_DEBUG_CACHE=1 npm run start
# Astro
npm run build
npm run preview
Der Prompt sollte eine Entscheidungstabelle verlangen, nicht nur Code:
Goal: classify every route in a Next.js/Astro site as SSR, SSG, ISR, or static export.
Inspect:
- app/ or src/pages/ routes
- cookies(), headers(), searchParams, connection(), cache: "no-store"
- generateStaticParams(), revalidate, output: "export", Astro prerender
- monetization pages, member pages, articles, product pages, and search pages
Constraints:
- Do not break SEO metadata or internal links
- Keep npm run build passing before and after
- Return a table with the chosen strategy, reason, touched files, and verification command
Konkrete Fallstricke
Erstens: nutzerspezifische Inhalte in statisches Artikel-HTML einbauen. Mitgliedsnamen, private Empfehlungen und versteckte Preise gehören nicht in SSG-HTML. Halte den Artikel statisch und verschiebe Personalisierung in eine Client-Komponente oder bewusst dynamische Sektion.
Zweitens: ISR-Intervalle zu niedrig setzen. revalidate = 1 verlagert Last oft zurück auf den Server. Wenn Präzision zählt, nutze On-Demand-Revalidation. Wenn Echtzeitdaten nötig sind, nutze SSR.
Drittens: Static Export wählen und später Server-Funktionen hinzufügen. Auth, Cookie-basierte UI, Server Route Handlers und ISR brauchen Runtime. Statisches Hosting ist stark, ersetzt aber keinen Server.
Viertens: Claude Codes schnell wirkenden Vorschlag ungeprüft übernehmen. Für eine monetarisierte Content-Site zählen auch OGP, strukturierte Daten, interne Links, Anzeigenposition, CTA-Tracking, LCP und CLS. Nach der Entscheidung hilft Performance-Optimierung mit Claude Code.
Empfehlung mit Monetarisierung
Für ein Content-Business wie ClaudeCodeLab sollte SSG der Standard für Artikel, Tutorials, Vergleiche und Einstiegseiten sein. ISR passt zu Produktlisten, Kategorien und News-ähnlichen Flächen. SSR gehört zu Konto, Suche, Warenkorb, Checkout-Kontext und allem, was private Request-Daten nutzt.
Starte mit dem kostenlosen Claude Code Cheatsheet, wenn du den Arbeitsablauf stabilisieren willst. Für Vorlagen und Implementierungspakete nutze die Produktseite. Wenn dein Team Routing-Strategie, Berechtigungen, Code Review, Analytics und Rollout-Training braucht, beginne mit Claude Code Training und Beratung.
Praktisch geprüft
Für diese Aktualisierung habe ich die offiziellen Seiten zu Next.js Dynamic Route Segments, connection, ISR, Static Exports, Astro on-demand rendering und Claude Code overview geprüft. In Masas Content-Workflow war die stabilste Aufteilung: SSG für Artikel, ISR für Produkt- und Kategorielisten, SSR für Konto und Suche. Der wichtigste Claude-Code-Schritt war die Routing-Matrix vor jeder Codeänderung. Sie machte versehentliche Cookie-Nutzung in statischen Seiten früh sichtbar und gab jeder Route eine Begründung plus Prüfkommando.
Kostenloses PDF: Claude-Code-Cheatsheet
E-Mail eintragen und eine Seite mit Befehlen, Review-Gewohnheiten und sicheren Workflows herunterladen.
Wir schützen Ihre Daten und senden keinen Spam.
Über den Autor
Masa
Engineer für praktische Claude-Code-Workflows und Team-Einführung.