Modul 9: Nuxt Fortgeschritten

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
// 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.

Terminal
# 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
// 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
// nuxt.config.ts
export default defineNuxtConfig({
  // SSR komplett deaktivieren → SPA-Modus
  ssr: false
})

// Alternativ nur bestimmte Seiten als SPA:
// → Siehe Hybrid Rendering weiter unten

Wann 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
// 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
// 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?

KriteriumSSRSSGSPAISR
SEO
Dynamische Daten⚡ (verzögert)
Performance⚡⚡⚡⚡⚡
Node.js ServerJaNeinNeinJa
Rails-ÄquivalentStandard RailsJekyll / MiddlemanRails API + ReactRails + Fragment Caching