SSR, SSG & SPA
Verstehe die verschiedenen Rendering-Modi von Nuxt und wähle den richtigen für dein Projekt – von Server-Side Rendering bis zur klassischen Single-Page-App.
Rendering-Modi im Überblick
Eines der mächtigsten Features von Nuxt ist die Flexibilität beim Rendering. Du kannst pro Projekt – oder sogar pro Route – entscheiden, wie Seiten generiert und ausgeliefert werden. Nuxt unterstützt vier Hauptmodi:
- SSR – Server-Side Rendering (Standard)
- SSG – Static Site Generation
- SPA – Client-Side Rendering
- Hybrid – Verschiedene Modi pro Route
Rails-Vergleich
Rails rendert standardmäßig serverseitig – genau wie Nuxt im SSR-Modus. Der Unterschied: Nuxt hydrisiert die Seite im Browser und wird zur interaktiven SPA, während Rails bei jedem Klick einen neuen Server-Request macht (es sei denn, du nutzt Turbo/Hotwire).
Server-Side Rendering (SSR)
SSR ist der Standard-Modus in Nuxt. Bei jedem Request rendert der Server die Vue-Komponenten zu HTML und schickt eine fertige Seite an den Browser. Anschließend wird die Seite im Browser „hydrisiert" – Vue übernimmt und macht sie interaktiv.
// nuxt.config.ts
export default defineNuxtConfig({
// SSR ist standardmäßig aktiviert
ssr: true
})
// Das ist identisch zu keiner Konfiguration –
// Nuxt nutzt SSR als Standard.Vorteile von SSR
- Schnelle erste Anzeige (First Contentful Paint)
- Volle SEO-Unterstützung – Crawler sehen fertiges HTML
- Funktioniert auch ohne JavaScript (Basis-Inhalt)
- Dynamische Inhalte werden bei jedem Request aktuell gerendert
SSR benötigt einen Node.js-Server. Du kannst Nuxt nicht einfach auf einem statischen Hosting wie GitHub Pages deployen, wenn du SSR nutzt. Verwende stattdessen Plattformen wie Vercel, Netlify oder einen eigenen Node.js-Server.
Static Site Generation (SSG)
Mit SSG generiert Nuxt zur Build-Zeit statische HTML-Dateien für jede Route. Das Ergebnis kann auf jedem Webserver oder CDN gehostet werden – kein Node.js-Server nötig.
# Statische Seiten generieren
npx nuxi generate
# Ergebnis liegt in .output/public/
# Kann auf jedem Webserver gehostet werden
# Vorschau der generierten Seite
npx nuxi preview Der Befehl nuxt generate crawlt automatisch alle verlinkten Seiten und generiert statisches HTML. Für dynamische Routen, die nicht verlinkt sind, musst du sie explizit angeben:
// nuxt.config.ts
export default defineNuxtConfig({
// Dynamische Routen für SSG definieren
hooks: {
async 'prerender:routes'(ctx) {
// z.B. Blog-Posts von API laden
const posts = await fetch('https://api.example.com/posts')
.then(r => r.json())
for (const post of posts) {
ctx.routes.add(`/blog/${post.slug}`)
}
}
}
})Wann SSG nutzen?
SSG eignet sich perfekt für Blogs, Dokumentation, Marketing-Seiten und alle Inhalte, die sich nicht bei jedem Request ändern. Die Seiten laden extrem schnell, weil sie vorgerendert sind und direkt vom CDN ausgeliefert werden.
Client-Side Rendering (SPA)
Im SPA-Modus deaktivierst du SSR komplett. Der Server liefert nur eine leere HTML-Hülle, und Vue rendert alles im Browser. Das ist der klassische Single-Page-Application-Ansatz.
// nuxt.config.ts
export default defineNuxtConfig({
// SSR komplett deaktivieren → SPA-Modus
ssr: false
})
// Alternativ nur bestimmte Seiten als SPA:
// → Siehe Hybrid Rendering weiter untenWann SPA nutzen?
- Admin-Dashboards hinter Login (SEO unwichtig)
- Interne Tools und Backoffice-Anwendungen
- Apps, die stark auf Browser-APIs angewiesen sind
- Wenn kein Node.js-Server verfügbar ist
SEO-Einschränkung
Im SPA-Modus sehen Suchmaschinen-Crawler nur eine leere Seite. Verwende diesen Modus nicht für Seiten, die in Suchmaschinen gefunden werden sollen.
Hybrid Rendering mit routeRules
Das Besondere an Nuxt: Du kannst verschiedene Rendering-Modi pro Route konfigurieren. So bekommst du das Beste aus allen Welten:
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
// Startseite: vorgerendert bei Build-Zeit
'/': { prerender: true },
// Blog: statisch generiert
'/blog/**': { prerender: true },
// Dashboard: Client-Only (SPA)
'/dashboard/**': { ssr: false },
// Produkte: ISR mit 1 Stunde Cache
'/produkte/**': { swr: 3600 },
// API: CORS-Header setzen
'/api/**': {
cors: true,
headers: { 'Access-Control-Allow-Origin': '*' }
}
}
})Wildcard-Patterns
Du kannst Glob-Patterns verwenden: /blog/** matcht alle Routen unter /blog/. So kannst du ganze Bereiche deiner App mit einem Modus konfigurieren.
ISR – Incremental Static Regeneration
ISR kombiniert die Vorteile von SSG und SSR: Seiten werden beim ersten Aufruf gerendert und dann für eine bestimmte Zeit gecacht. Nach Ablauf der Cache-Zeit wird die Seite im Hintergrund neu generiert.
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
// ISR: Seite 1 Stunde cachen, dann im Hintergrund erneuern
'/blog/**': { swr: 3600 },
// ISR mit kürzerem Cache für häufig aktualisierte Seiten
'/news/**': { swr: 600 }, // 10 Minuten
// Immer frisch vom Server (kein Cache)
'/dashboard/**': { swr: false },
// Einmal generieren, nie erneuern
'/about': { prerender: true }
}
}) Mit swr: 3600 (Stale-While-Revalidate) wird die Seite eine Stunde gecacht. Danach wird beim nächsten Request die alte Version ausgeliefert, während im Hintergrund eine neue Version generiert wird.
ISR funktioniert nur mit bestimmten Hosting-Plattformen (Vercel, Netlify, Cloudflare). Auf einem eigenen Server kannst du stattdessen swr: true mit einem Cache-Layer wie Redis verwenden.
Welchen Modus wählen?
| Kriterium | SSR | SSG | SPA | ISR |
|---|---|---|---|---|
| SEO | ✅ | ✅ | ❌ | ✅ |
| Dynamische Daten | ✅ | ❌ | ✅ | ⚡ (verzögert) |
| Performance | ⚡ | ⚡⚡⚡ | ⚡ | ⚡⚡ |
| Node.js Server | Ja | Nein | Nein | Ja |
| Rails-Äquivalent | Standard Rails | Jekyll / Middleman | Rails API + React | Rails + Fragment Caching |