Next.js 15: Komplette Anleitung zu Server Components
Im Jahr 2026 nutzen 78% der neuen Next.js-Projekte den App Router mit Server Components. Das ist nicht nur ein Trend—es ist ein neues Paradigma für Fullstack-Entwicklung, das unsere Herangehensweise an Performance, SEO und React-Architektur verändert.
Was Sie lernen:
- ✅ Wie Hydration funktioniert und warum RSC sie eliminiert
- ✅ Muster zur Trennung von Client/Server-Komponenten
- ✅ Caching und Streaming in Next.js 15
- ✅ Migration vom Pages Router zum App Router
1. Architektur der Server Components
React Server Components (RSC) sind Komponenten, die ausschließlich auf dem Server rendern. Sie erreichen nie das Client-Bundle und bieten drei entscheidende Vorteile:
| Merkmal | Server Component | Client Component |
|---|---|---|
| Ausführungsort | Nur Server (Node.js/Edge) | Server + Browser |
| Bundle-Größe | 0 KB (nie an Client gesendet) | Kompletter Komponentencode |
| Datenbank/API-Zugriff | ✅ Direkter Zugriff | ❌ Nur via fetch/API-Routen |
| Interaktivität | ❌ Kein useState/useEffect | ✅ Volle Interaktivität |
| SEO | ✅ Komplettes HTML in Antwort | ⚠️ Erfordert SSR/SSG |
💡 Tipp: Standardmäßig sind alle Komponenten im App Router Server Components. Um eine Komponente clientseitig zu machen, fügen Sie die Direktive 'use client' am Dateianfang hinzu. Verwenden Sie sie nicht unnötig—jede Client-Komponente erhöht die JavaScript-Bundle-Größe.
2. Hydration und Zero-Bundle-Size
Traditionelles SSR (Pages Router) folgt diesem Muster: Server-Rendering → HTML senden → JS laden → Hydration → Interaktivität. Das Problem: React muss den gesamten HTML "wiederbeleben", indem es virtuellen DOM mit dem echten vergleicht.
Mit Server Components ändert sich dieser Prozess radikal:
// app/page.tsx — Server Component standardmäßig
import { db } from '@/lib/db' // ✅ Direkter Import auf Server
export default async function ProductPage() {
// ✅ Direkte Datenbankabfrage ohne API-Layer
const products = await db.query('SELECT * FROM products')
return (
Produktkatalog
{products.map(p => (
))}
)
}
In diesem Beispiel läuft db.query nur auf dem Server. Der Client erhält fertiges HTML ohne Datenbankverbindungscode. Einsparung: ~15-40 KB JavaScript auf einer typischen Katalogseite.
⚠️ Wichtig: Server Components können keine Browser-APIs (window, document, localStorage) oder React-State-Hooks (useState, useEffect, useContext) verwenden. Für interaktive Elemente erstellen Sie Client-Komponenten und importieren Sie diese in Server Components.
3. Muster zur Komponententrennung
Die Grenze zwischen Server und Client ist eine wichtige architektonische Entscheidung. Hier bewährte Muster aus Produktionsprojekten 2026:
Muster „Client-Blätter"
Machen Sie Server Components zum „Stamm" des Baums, interaktive Elemente zu „Blättern":
// app/product/[id]/page.tsx — Server Component
import { AddToCartButton } from './AddToCartButton' // Client Component
import { db } from '@/lib/db'
export default async function ProductPage({ params }: { params: { id: string } }) {
const product = await db.products.findUnique({ where: { id: params.id } })
return (
{product.name}
{product.description}
{/* ✅ Nur der Button ist Client-Komponente */}
)
}
Muster „Komposition"
Übergeben Sie Server Components als children an Client Components:
// components/Modal.tsx — Client Component
'use client'
export function Modal({ children, trigger }: { children: React.ReactNode, trigger: React.ReactNode }) {
const [open, setOpen] = useState(false)
return (
<>
{open && {children}}
>
)
}
// app/page.tsx — Server Component
import { Modal } from '@/components/Modal'
import { ProductList } from './ProductList' // Server Component
export default function Page() {
return (
{/* ✅ ProductList rendert auf Server, zeigt sich aber im Client-Modal */}
)
}
💡 Tipp: Verwenden Sie @next/bundle-analyzer, um zu sehen, welche Komponenten im Client-Chunk landen. Ziel: Minimieren Sie 'use client'-Direktiven auf höheren Baumebenen.
4. Caching und Partial Prerendering
Next.js 15 brachte eine revolutionäre Funktion—Partial Prerendering (PPR). Es ist eine Hybridlösung aus statischer Generierung und dynamischem Streaming:
// next.config.js
module.exports = {
experimental: {
ppr: true, // Partial Prerendering aktivieren
},
}
// app/page.tsx
import { Suspense } from 'react'
import { StaticHeader } from './StaticHeader' // Statische Komponente
import { DynamicReviews } from './DynamicReviews' // Dynamische Komponente
export default function Page() {
return (
<>
{/* ✅ Bei Build vorgebaut */}
{/* 🔄 Bei Anfrage gestreamt mit Fallback */}
}>
>
)
}
Ergebnis: Time to First Byte (TTFB) um 60-80% reduziert im Vergleich zu reinem SSR, während Nutzer Inhalte sofort sehen.
| Strategie | Wann verwenden | TTFB |
|---|---|---|
| Static Generation | Unveränderlicher Inhalt (Doku, Landingpages) | ~50ms (CDN) |
| Partial Prerendering | Gemischter Inhalt (E-Commerce, Blogs) | ~100-200ms |
| Dynamic Streaming | Personalisierter Inhalt (Dashboards) | ~200-500ms |
| Traditionelles SSR | Legacy Pages Router Projekte | ~300-800ms |
5. Migration vom Pages Router
Laut State of React 2026 Umfrage haben 64% der Unternehmen bereits migriert oder befinden sich im Übergang zum App Router. Hier ist ein schrittweiser Plan:
// 1. Paralleles Routing (vorhandener Code funktioniert weiter)
app/
├── (marketing)/ # Neue Seiten auf App Router
│ ├── page.tsx
│ └── about/page.tsx
├── api/ # API-Routen bleiben in pages/api/
└── ...
pages/ # Alte Seiten funktionieren unverändert
├── index.tsx
├── about.tsx
└── api/
Schritt 1: Erstellen Sie den Ordner app/(marketing) für neue Seiten. Klammern schließen das Segment von der URL aus.
Schritt 2: Migrieren Sie Seiten einzeln, beginnend mit einfachen (statischer Inhalt).
Schritt 3: Für komplexe Seiten nutzen Sie inkrementelle Komponentenmigration.
⚠️ Wichtig: getServerSideProps und getStaticProps funktionieren nicht im App Router. Fordern Sie Daten direkt in Komponenten via fetch oder ORM an. Für Caching nutzen Sie fetch('/api', { next: { revalidate: 60 } }) oder unstable_cache.
6. Produktionsreife Muster
Fehlerbehandlung
// app/error.tsx — Error Boundary für Segment
'use client'
export default function ErrorBoundary({ error, reset }: { error: Error, reset: () => void }) {
return (
Etwas ist schiefgelaufen
)
}
// app/not-found.tsx — 404 Seite
export default function NotFound() {
return (
Seite nicht gefunden
Zur Startseite
)
}
Loading-Zustände
// app/loading.tsx — Automatisch beim Laden angezeigt
export default function Loading() {
return Wird geladen...
}
// Oder granulär mit Suspense
import { Suspense } from 'react'
}>
💡 Tipp: Nutzen Sie loading.tsx für sofortiges Feedback bei Navigation. Next.js zeigt es automatisch beim Wechsel zwischen Seiten, was die wahrgenommene Performance verbessert.
Bereit für Next.js 15?
Wir helfen Teams bei der Migration zum App Router ohne Downtime. Architektur-Audit, phasenweise Migration, Core Web Vitals Optimierung.
Fazit
Next.js 15 mit Server Components ist nicht nur eine neue Framework-Version—es ist ein fundamentaler Wandel in der Webanwendungsarchitektur. Die Eliminierung von Hydration, Zero-Bundle-Size-Komponenten und Partial Prerendering bieten echte Geschäftsvorteile: Geschwindigkeit, SEO und reduzierte Infrastrukturkosten.
Schlüsselprinzipien für Produktion:
- Server First — beginnen Sie mit Server Components, fügen Sie Client-Interaktivität nur wo nötig hinzu
- Granularität — je tiefer 'use client' im Baum, desto kleiner das Bundle
- PPR — nutzen Sie Partial Prerendering für komplexe Seiten
- Inkrementalität — migrieren Sie schrittweise, Seite für Seite
Die nächste Ära von React ist hier. Bleiben Sie nicht beim Pages Router—die Zukunft gehört den Server Components! 🚀