# 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 ``` 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