# Nuxt 3: SSR und statische Generierung, der vollständige Leitfaden
> SSR und statische Generierung mit Nuxt 3 meistern. Von useFetch bis Route Rules: So lässt sich die Performance von Vue.js-Anwendungen optimieren.
- Published: 2026-02-11
- Updated: 2026-04-28
- Author: SharpSkill
- Tags: nuxt 3, vue.js, ssr, statische generierung, web-performance
- Reading time: 12 min
---
Nuxt 3 verändert die Art und Weise, wie Vue.js-Anwendungen gebaut werden, indem es mehrere Rendering-Modi für unterschiedliche Anwendungsfälle bereitstellt. Vom Server-Side Rendering (SSR) über die statische Generierung bis hin zum hybriden Rendering bietet das Framework bemerkenswerte Flexibilität, um Performance und SEO zu optimieren.
> **Voraussetzungen**
>
> Dieses Tutorial setzt grundlegende Kenntnisse von Vue 3 und der Composition API voraus. Vertrautheit mit Konzepten des serverseitigen Renderings ist hilfreich, aber nicht zwingend erforderlich, da die Grundlagen im Verlauf des Leitfadens erklärt werden.
## Die Rendering-Modi von Nuxt 3 verstehen
Bevor man in den Code eintaucht, ist es wichtig, die Unterschiede zwischen den verfügbaren Rendering-Modi zu verstehen. Jeder Modus deckt spezifische Anforderungen in Bezug auf Performance, SEO und Benutzererfahrung ab.
SSR (Server-Side Rendering) generiert das HTML serverseitig bei jeder Anfrage. Die statische Generierung (SSG) erzeugt alle Seiten zur Build-Zeit. Der Hybridmodus erlaubt es, beide Ansätze pro Seite zu kombinieren.
```typescript
// nuxt.config.ts
// Konfiguration der verschiedenen Rendering-Modi
export default defineNuxtConfig({
// SSR standardmäßig aktiviert (für SEO empfohlen)
ssr: true,
// Statische Generierung: rendert alle Seiten vorab
// 'npm run generate' verwenden, um zu bauen
// target: 'static', // Nuxt-2-Syntax
// Hybridmodus: pro Route konfigurierbar
routeRules: {
// Startseite: vorgerendert und im Cache
'/': { prerender: true },
// Blog: statische Generierung
'/blog/**': { prerender: true },
// Dashboard: Rendering ausschließlich im Client
'/dashboard/**': { ssr: false },
// API: kein Pre-Rendering
'/api/**': { prerender: false }
}
})
```
Diese Konfiguration zeigt die Stärke des Hybridmodus: Jeder Bereich der Anwendung verwendet den Rendering-Modus, der seinen Anforderungen am besten entspricht.
## Datenabfrage mit useFetch und useAsyncData
Nuxt 3 stellt zwei Hauptkomposables für isomorphes Datenladen bereit. Diese Komposables funktionieren sowohl serverseitig als auch clientseitig und übernehmen die Hydration automatisch.
`useFetch` ist ein Wrapper um `useAsyncData`, der HTTP-Aufrufe vereinfacht. `useAsyncData` bietet mehr Kontrolle für fortgeschrittene Anwendungsfälle.
```vue
Artikel wird geladen...
{{ article.title }}
```
Für Fälle, die mehr Kontrolle erfordern, erlaubt `useAsyncData` die Ausführung beliebiger asynchroner Funktionen.
```vue
```
Diese Komposables vermeiden Doppel-Fetches: Auf dem Server geladene Daten werden in das HTML-Payload serialisiert und während der clientseitigen Hydration wiederverwendet.
## SSR mit Server-Hooks anpassen
Das SSR von Nuxt 3 lässt sich über Server-Hooks anpassen. Diese Hooks erlauben Eingriffe in verschiedenen Phasen des Rendering-Zyklus, um das Standardverhalten zu modifizieren.
```typescript
// server/plugins/render-hooks.ts
// Server-Plugin zur Anpassung des SSR-Renderings
export default defineNitroPlugin((nitroApp) => {
// Hook, der vor dem Rendern jeder Seite ausgeführt wird
nitroApp.hooks.hook('render:html', (html, { event }) => {
// Skripte oder Metadaten injizieren
html.head.push(`
`)
})
// Hook für die Verwaltung des Render-Caches
nitroApp.hooks.hook('render:response', (response, { event }) => {
// Eigene Cache-Header hinzufügen
const path = event.path
if (path.startsWith('/blog/')) {
// Langer Cache für Blogartikel
response.headers['Cache-Control'] = 'public, max-age=3600, s-maxage=86400'
} else if (path.startsWith('/api/')) {
// Kein Cache für APIs
response.headers['Cache-Control'] = 'no-store'
}
})
})
```
> **SSR-Performance**
>
> Der Hook `render:response` eignet sich ideal, um HTTP-Cache-Strategien umzusetzen. Die Kombination aus SSR und einem CDN, das Cache-Control-Header respektiert, ermöglicht es, vorgerenderte Seiten auszuliefern und sie bei Bedarf gezielt zu invalidieren.
## Statische Generierung mit nuxt generate
Die statische Generierung baut alle Seiten zur Build-Zeit vorab. Dieser Ansatz eignet sich ideal für Websites mit stabilem Inhalt wie Blogs, Dokumentationen oder Marketing-Seiten.
Für dynamische Routen muss Nuxt alle zu generierenden URLs kennen. Der Hook `prerender:routes` erlaubt es, diese Routen programmatisch zu definieren.
```typescript
// nuxt.config.ts
// Vollständige Konfiguration für statische Generierung
export default defineNuxtConfig({
// Statische Generierung aktivieren
nitro: {
prerender: {
// Automatisches Crawlen von Links aktivieren
crawlLinks: true,
// Routen, die immer enthalten sein müssen
routes: ['/', '/about', '/contact'],
// Bestimmte Routen ignorieren
ignore: ['/admin', '/api']
}
},
hooks: {
// Hook zum Erzeugen dynamischer Routen
async 'prerender:routes'(ctx) {
// Artikel aus API oder DB laden
const articles = await fetch('https://api.example.com/articles')
.then(res => res.json())
// Artikel-Routen hinzufügen
for (const article of articles) {
ctx.routes.add(`/blog/${article.slug}`)
}
// Kategorien laden
const categories = await fetch('https://api.example.com/categories')
.then(res => res.json())
for (const category of categories) {
ctx.routes.add(`/category/${category.slug}`)
}
}
}
})
```
Für Projekte mit vielen Seiten kann der automatische Crawler unzureichend sein. Hier ist ein robusterer Ansatz mit einer separaten Konfigurationsdatei.
```typescript
// server/utils/generate-routes.ts
// Hilfsfunktion zur Generierung der Liste dynamischer Routen
import { prisma } from './prisma'
export async function getAllStaticRoutes(): Promise {
const routes: string[] = []
// Blogartikel
const articles = await prisma.article.findMany({
where: { published: true },
select: { slug: true, category: { select: { slug: true } } }
})
for (const article of articles) {
routes.push(`/blog/${article.category.slug}/${article.slug}`)
}
// Produktseiten
const products = await prisma.product.findMany({
where: { active: true },
select: { slug: true }
})
for (const product of products) {
routes.push(`/products/${product.slug}`)
}
// Tag-Seiten
const tags = await prisma.tag.findMany({
select: { slug: true }
})
for (const tag of tags) {
routes.push(`/tags/${tag.slug}`)
}
return routes
}
```
## Hybrides Rendering mit routeRules
Das hybride Rendering ist das Aushängeschild von Nuxt 3. Es erlaubt, pro Route unterschiedliche Rendering-Regeln zu definieren und so das Beste aus SSR und SSG zu kombinieren.
```typescript
// nuxt.config.ts
// Erweiterte Konfiguration für hybrides Rendering
export default defineNuxtConfig({
routeRules: {
// Marketing-Seiten: vorgerendert und langfristig im Cache
'/': { prerender: true },
'/pricing': { prerender: true },
'/features/**': { prerender: true },
// Blog: ISR (Incremental Static Regeneration)
// Revalidierung jede Stunde
'/blog/**': {
isr: 3600,
prerender: true
},
// Dokumentation: CDN-Cache mit Revalidierung
'/docs/**': {
swr: 86400, // Stale-while-revalidate
prerender: true
},
// E-Commerce: SSR mit kurzem Cache
'/products/**': {
ssr: true,
cache: {
maxAge: 60,
staleMaxAge: 300
}
},
// Warenkorb und Checkout: ausschließlich Client
'/cart': { ssr: false },
'/checkout/**': { ssr: false },
// Dashboard: SPA-Modus
'/dashboard/**': {
ssr: false,
// Pre-Rendering deaktivieren
prerender: false
},
// API-Routen: standardmäßig kein Cache
'/api/**': {
cors: true,
headers: {
'Access-Control-Allow-Methods': 'GET,POST,PUT,DELETE'
}
}
}
})
```
Diese Konfiguration veranschaulicht eine typische Architektur moderner Anwendungen: Öffentliche Seiten werden mit SSG für SEO optimiert, während interaktive Bereiche auf clientseitiges Rendering setzen.
## Performance-Optimierung mit Daten-Caching
Über das Seiten-Caching hinaus erlaubt Nuxt 3, geladene Daten zu cachen. Diese Strategie reduziert die Last auf APIs und verbessert die Antwortzeiten.
```typescript
// server/api/articles/[slug].get.ts
// API-Endpunkt mit Daten-Caching
import { getArticleBySlug } from '~/server/utils/articles'
export default defineCachedEventHandler(
async (event) => {
const slug = getRouterParam(event, 'slug')
if (!slug) {
throw createError({
statusCode: 400,
message: 'Slug fehlt'
})
}
const article = await getArticleBySlug(slug)
if (!article) {
throw createError({
statusCode: 404,
message: 'Artikel nicht gefunden'
})
}
return article
},
{
// Cache-Schlüssel basierend auf dem Slug
getKey: (event) => `article-${getRouterParam(event, 'slug')}`,
// Cache-Dauer: 1 Stunde
maxAge: 3600,
// Stale-while-revalidate: alten Cache während der Aktualisierung ausliefern
staleMaxAge: 7200,
// Tag-basierte Invalidierung
tags: ['articles']
}
)
```
Um den Cache bei Inhaltsänderungen zu invalidieren, stellt Nuxt ein Tag-System bereit.
```typescript
// server/api/articles/[slug].put.ts
// Artikel-Update mit Cache-Invalidierung
import { updateArticle } from '~/server/utils/articles'
export default defineEventHandler(async (event) => {
const slug = getRouterParam(event, 'slug')
const body = await readBody(event)
// Artikel aktualisieren
const article = await updateArticle(slug, body)
// Cache für diesen Artikel invalidieren
await useStorage('cache').removeItem(`nitro:handlers:article-${slug}`)
// Oder Tag-basierte Invalidierung (alle Artikel)
// await useStorage('cache').clear('articles')
return article
})
```
> **Verteilter Cache**
>
> In der Produktion mit mehreren Instanzen reicht ein In-Memory-Cache nicht aus. Es empfiehlt sich, Redis oder ein anderes verteiltes System über die Nitro-Konfiguration einzurichten, um Konsistenz zwischen den Instanzen sicherzustellen.
## SEO und Metadaten verwalten
SSR ermöglicht SEO-Optimierung, indem Metadaten serverseitig generiert werden. Nuxt 3 bietet mehrere Ansätze, um Meta-Tags dynamisch zu verwalten.
```vue
```
Für statische Seiten lassen sich die Metadaten direkt in der Komponente definieren.
```vue
```
## Deployment und Produktionsüberlegungen
Die Wahl des Deployments hängt vom verwendeten Rendering-Modus ab. Hier die wichtigsten Optionen und ihre Konfigurationen.
```typescript
// nuxt.config.ts
// Konfiguration für verschiedene Deployment-Umgebungen
export default defineNuxtConfig({
nitro: {
// Preset je nach Zielplattform
// preset: 'vercel', // Vercel
// preset: 'netlify', // Netlify
// preset: 'cloudflare-pages', // Cloudflare
// preset: 'node-server', // Klassisches Node.js
// Konfiguration für Node.js in der Produktion
preset: 'node-server',
// Antwort-Komprimierung
compressPublicAssets: true,
// Konfiguration des Cache-Storages
storage: {
cache: {
driver: 'redis',
url: process.env.REDIS_URL
}
}
},
// Umgebungsvariablen zur Laufzeit
runtimeConfig: {
// Geheimnisse (nicht an den Client weitergegeben)
apiSecret: process.env.API_SECRET,
// Öffentliche Konfiguration
public: {
apiBase: process.env.NUXT_PUBLIC_API_BASE || '/api'
}
}
})
```
Für ein statisches Deployment erzeugt der Befehl `npm run generate` einen Ordner `.output/public`, der bereit ist, auf jedem Static-File-Host bereitgestellt zu werden.
```bash
# Statische Generierung
npm run generate
# Der Inhalt von .output/public lässt sich bereitstellen auf:
# - Vercel (automatische Erkennung)
# - Netlify (automatische Konfiguration)
# - GitHub Pages
# - S3 + CloudFront
# - Jedem CDN oder Static-File-Server
```
## Fazit
Nuxt 3 bietet außergewöhnliche Flexibilität beim Rendern von Vue.js-Anwendungen. Die Wahl zwischen SSR, SSG und hybridem Rendering hängt von den spezifischen Anforderungen jedes Projekts ab.
**Kernpunkte:**
✅ **SSR**: ideal für dynamische Inhalte, die gutes SEO erfordern (E-Commerce, Nachrichtenseiten)
✅ **SSG**: perfekt für stabile Inhalte (Blogs, Dokumentation, Marketing-Seiten)
✅ **Hybrid**: der beste Ansatz für komplexe Anwendungen mit unterschiedlichen Anforderungen
✅ **useFetch/useAsyncData**: automatische Hydration und Cache-Verwaltung
✅ **routeRules**: feingranulare Konfiguration für das Verhalten jeder Route
✅ **Caching**: vielfältige Strategien zur Optimierung der Performance in der Produktion
Die Kombination aus hybridem Rendering und einer durchdachten Cache-Strategie ermöglicht den Aufbau performanter Anwendungen, die SEO-optimiert sind und gleichzeitig die Interaktivität von Single Page Applications bewahren.
---
Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack.
HTML version of this page: https://sharpskill.dev/de/blog/vue-nuxt/nuxt-3-ssr-static-generation