Modul 12: Deployment

Build-Modi

SSR, Static und SPA — die verschiedenen Deployment-Strategien von Nuxt

Drei Wege zum Deployment

Nuxt unterstützt drei Build-Modi, die sich grundlegend darin unterscheiden, wann und wo dein HTML generiert wird:

  • SSR (nuxt build) — Server rendert HTML bei jedem Request
  • SSG (nuxt generate) — HTML wird beim Build generiert (statisch)
  • SPA — Nur Client-seitiges Rendering, keine Server-Logik
🛤️

Rails-Vergleich

Rails-Apps werden fast immer als SSR deployed — der Server rendert bei jedem Request. Nuxt gibt dir zusätzlich die Option, Seiten beim Build vorzurendern (wie Jekyll) oder als reine Client-App auszuliefern (wie eine klassische Vue-SPA).

SSR-Produktion: nuxt build

Der Standardmodus: Nuxt baut einen Node.js-Server, der HTML bei jedem Request serverseitig rendert. Ideal für dynamische Inhalte und SEO.

Terminal
# Produktions-Build erstellen
npx nuxt build

# Server starten
node .output/server/index.mjs

# Oder mit dem Nuxt-CLI
npx nuxt preview
Build-Ausgabe
  ✓ Client built in 3.2s
  ✓ Server built in 1.8s

  .output/
  ├── server/
  │   ├── index.mjs        ← Node.js Server-Einstiegspunkt
  │   ├── chunks/           ← Server-Code (API-Routen, etc.)
  │   └── node_modules/     ← Server-Dependencies
  ├── public/
  │   ├── _nuxt/            ← Client-Assets (JS, CSS)
  │   └── favicon.ico
  └── nitro.json            ← Server-Konfiguration
ℹ️

Wann SSR?

  • Dynamische Inhalte (Nutzerdaten, Echtzeitdaten)
  • SEO ist wichtig (Suchmaschinen sehen fertiges HTML)
  • Server-API-Routen werden genutzt
  • Authentifizierung mit serverseitigen Sessions

Statische Generierung: nuxt generate

Bei der statischen Generierung werden alle Seiten beim Build als HTML-Dateien erzeugt. Kein Server nötig — du kannst das Ergebnis auf jedem Webserver oder CDN hosten.

Terminal
# Statische Seiten generieren
npx nuxt generate

# Vorschau mit einfachem HTTP-Server
npx serve .output/public
nuxt.config.ts
export default defineNuxtConfig({
  // Routen, die vorgerendert werden sollen
  // (Standard: alle verlinkten Seiten werden gecrawlt)
  nitro: {
    prerender: {
      // Zusätzliche Routen manuell angeben
      routes: ['/sitemap.xml', '/blog/archiv'],

      // Crawl-Tiefe für automatisches Finden von Routen
      crawlLinks: true,

      // Routen ignorieren
      ignore: ['/api/**', '/admin/**']
    }
  }
})
💡

Wann Static?

  • Blog, Dokumentation, Marketing-Seiten
  • Inhalte ändern sich selten
  • Maximale Performance (vorab generiertes HTML)
  • Hosting auf CDN/GitHub Pages/Netlify
  • Keine Server-Infrastruktur gewünscht

SPA-Modus

Im SPA-Modus wird kein Server-Rendering durchgeführt. Die App läuft komplett im Browser — wie eine klassische Vue-App:

nuxt.config.ts
export default defineNuxtConfig({
  // SSR komplett deaktivieren
  ssr: false,

  // Alternativ: Hybrid — bestimmte Routen als SPA
  routeRules: {
    // Diese Routen als SPA rendern (kein SSR)
    '/dashboard/**': { ssr: false },
    '/admin/**': { ssr: false },

    // Diese Routen statisch vorrendern
    '/blog/**': { prerender: true },

    // Diese Routen immer serverseitig rendern
    '/': { ssr: true }
  }
})
⚠️

SPA-Einschränkungen

  • Kein SEO (Suchmaschinen sehen leeres HTML)
  • Langsamerer erster Seitenaufruf (JS muss erst laden)
  • Server-API-Routen funktionieren weiterhin
  • Sinnvoll für authentifizierte Bereiche (Dashboard, Admin)

Bundle-Größe analysieren

Um die Größe deiner App zu verstehen und Optimierungspotenzial zu finden:

Terminal
# Bundle-Analyzer aktivieren
npx nuxt analyze

# Öffnet einen interaktiven Bericht im Browser:
# - Zeigt alle Chunks und ihre Größen
# - Identifiziert große Dependencies
# - Hilft beim Code-Splitting

# Alternativ in nuxt.config.ts:
# build: {
#   analyze: true
# }
nuxt.config.ts — Performance-Optimierung
export default defineNuxtConfig({
  // Vite Build-Optionen
  vite: {
    build: {
      // Chunk-Größen-Warnung
      chunkSizeWarningLimit: 500,

      rollupOptions: {
        output: {
          // Manuelle Chunk-Aufteilung
          manualChunks: {
            'primevue': ['primevue'],
            'pinia': ['pinia']
          }
        }
      }
    }
  },

  // Nuxt-spezifische Optimierungen
  experimental: {
    // Payload-Extraktion für statische Seiten
    payloadExtraction: true,

    // Treeshaking für Client-Bundle
    treeshakeClientOnly: true
  },

  // Nur benötigte Komponenten laden (PrimeVue)
  // → Siehe PrimeVue-Kapitel für Details
})

Performance-Tipps

Optimierungscheckliste
✅ Performance-Checkliste für Nuxt-Deployment
──────────────────────────────────────────────

Bilder:
  □ Nuxt Image für automatische Optimierung
  □ Lazy Loading für Below-the-Fold-Bilder
  □ WebP/AVIF-Format nutzen

Code:
  □ Bundle-Analyse durchführen (nuxt analyze)
  □ Große Libraries prüfen (brauche ich alles?)
  □ Dynamic Imports für schwere Komponenten
  □ Tree-Shaking aktiv (keine * Imports)

Rendering:
  □ Hybrid-Modus: Statisch wo möglich, SSR wo nötig
  □ Caching-Header für statische Assets
  □ CDN für statische Dateien

Server:
  □ Kompression aktivieren (gzip/brotli)
  □ Keep-Alive Connections
  □ Health-Check Endpunkt
💡

Vergleich der Build-Modi

EigenschaftSSRSSGSPA
Server nötig✅ Ja❌ Nein❌ Nein
SEO✅ Gut✅ Gut❌ Schlecht
Dynamische Daten✅ Ja⚠️ Bei Build✅ Ja
Erster Seitenaufruf✅ Schnell✅ Sehr schnell⚠️ Langsamer
Server-API✅ Ja⚠️ Eingeschränkt⚠️ Extern

Zusammenfassung

💡

Build-Modi auf einen Blick

  • nuxt build — SSR-Server mit Node.js (.output/server/)
  • nuxt generate — Statische HTML-Dateien (.output/public/)
  • ssr: false — SPA-Modus ohne Server-Rendering
  • routeRules — Hybrid-Modus: SSR + Static + SPA pro Route
  • nuxt analyze — Bundle-Größe analysieren