Design wechseln

Next.js App Router in der Praxis: Route Groups und Nested Layouts gegen Verzeichnis-Chaos in großen Projekten

Easton editorial illustration: build pipeline conveyor

Im VS-Code-Dateibaum: über 120 Ordner unter app. Sie suchen die Benutzerverwaltung im Admin-Bereich und wechseln fünf Minuten lang zwischen dashboard-user-list, admin-users und backend-user-management – alle sehen plausibel aus.

Beim Code-Review fügt jemand eine /about-Route hinzu – und kollidiert mit der Marketing-/about von letzter Woche. Zwei Seiten, ein Pfad, niemand will nachgeben.

Am Anfang wirkte die flache Struktur bei einem Dutzend Seiten noch aufgeräumt. Nach sechs Monaten und zehnfach mehr Funktionen gleicht app/ einem unaufgeräumten Kleiderschrank: alles ist drin, aber finden kostet Zeit.

Wenn Sie ein Next.js-Projekt betreiben, im Team mehr als drei Personen arbeiten und über 50 Seiten haben, kennen Sie das Problem. Der App Router bietet vier Features dafür: Route Groups, Nested Layouts, Parallel Routes und Intercepting Routes. Die meisten Tutorials bleiben bei Hello-World-Demos – in echten Projekten fehlt oft der rote Faden.

Dieser Artikel zeigt anhand eines E-Commerce-Beispiels, wie die vier Features zusammenspielen und wie Sie ein chaotisches Verzeichnis in eine wartbare, skalierbare Struktur überführen.

Schmerzpunkte – drei Probleme klassischer Verzeichnisstrukturen

Die Falle der flachen Verzeichnisse

So sah unsere frühere Struktur aus:

app/
├── page.tsx              # Startseite
├── about/page.tsx        # Über uns
├── products/page.tsx     # Produktliste
├── product-detail/[id]/page.tsx
├── cart/page.tsx
├── checkout/page.tsx
├── dashboard/page.tsx    # Admin-Startseite
├── dashboard-users/page.tsx
├── dashboard-users-active/page.tsx
├── dashboard-users-blocked/page.tsx
├── dashboard-orders/page.tsx
├── dashboard-orders-pending/page.tsx
├── dashboard-settings/page.tsx
├── auth-login/page.tsx   # Login
├── auth-register/page.tsx
└── ... (noch 80+ Ordner)

Schon beim Anblick unübersichtlich. Schlimmer: URLs wie /dashboard-users-active statt /dashboard/users/active. Präfixe vermeiden Konflikte, kaschieren aber nur das eigentliche Problem.

Auf einen Blick erkennen Sie nicht, welche Seiten zum Frontend, Admin oder Auth gehören. Neue Teammitglieder brauchen Tage, um sich zurechtzufinden.

Doppelte Layouts und hoher Wartungsaufwand

Frontend und Admin haben völlig unterschiedliche Layouts: oben Navigation und Footer vs. Sidebar und Berechtigungsprüfung. Klassisch importiert jede Seite das Layout manuell:

// app/dashboard-users/page.tsx
import DashboardLayout from '@/components/DashboardLayout'

export default function UsersPage() {
  return (
    <DashboardLayout>
      <div>Benutzerverwaltung</div>
    </DashboardLayout>
  )
}

Probleme: Neue Admin-Seiten ohne Layout wirken „nackt“. Manche nutzen DashboardLayout, andere AdminLayout. Eine Sidebar-Änderung kann 20 Dateien betreffen.

Modals und Pop-ups am Routing-Hindernis

Anforderung: Klick auf ein Produkt in der Liste öffnet ein Modal mit Details, die URL wird /product/123 – teilbar per Link. Klingt simpel, ist es nicht.

Klassisch: Client-State für Modal, manuelle URL-Manipulation. Nach Reload verschwindet das Modal. Zwei Versionen (Modal + Vollseite) bedeuten doppelte Pflege – jede Produktänderung an zwei Stellen.

Instagram-ähnliches Verhalten – Liste, Klick, Modal, Reload zeigt Vollbild – ist mit traditionellem Routing mühsam.

Route Groups – logische Gruppierung ohne URL-Änderung

Was sind Route Groups?

Ordner in Klammern, z. B. (marketing) – der Name erscheint nicht in der URL:

app/
├── (marketing)/           # Marketing-Gruppe
│   ├── layout.tsx         # Frontend-Layout
│   ├── page.tsx           # URL: /
│   ├── about/page.tsx     # URL: /about
│   └── products/page.tsx  # URL: /products
├── (shop)/                # Shop-Gruppe
│   ├── layout.tsx
│   ├── cart/page.tsx      # URL: /cart
│   └── checkout/page.tsx  # URL: /checkout
└── (dashboard)/           # Admin-Gruppe
    ├── layout.tsx
    ├── dashboard/page.tsx # URL: /dashboard
    ├── users/page.tsx     # URL: /users
    └── orders/page.tsx    # URL: /orders

(marketing)/about/page.js bleibt /about, nicht /marketing/about.

Der Kernwert: Code organisieren, nicht URLs verlängern. Gruppierung nach Business, Team oder Modul – übersichtlich, ohne lange Pfade.

Praxis: Gruppierung nach Teams

Drei Teams: Marketing (Website), Produkt (Shop), Backend (Admin). Früher alle in einem app/-Ordner – ständige Git-Konflikte. Mit Route Groups:

app/
├── (team-marketing)/      # Marketing-Team
│   ├── layout.tsx
│   ├── page.tsx           # Startseite
│   ├── about/page.tsx
│   └── pricing/page.tsx
├── (team-product)/        # Produkt-Team
│   ├── layout.tsx
│   ├── products/page.tsx
│   └── product/[id]/page.tsx
└── (team-backend)/        # Backend-Team
    ├── layout.tsx
    ├── dashboard/page.tsx
    └── admin/page.tsx

Vorteile:

  1. Weniger Dateikonflikte – jedes Team arbeitet in seinem Bereich.
  2. Klarere Code Reviews – PRs zeigen sofort betroffenes Team.
  3. Eigene Layouts pro Gruppe, ohne manuellen Import in jeder Seite.

Alternative: Gruppierung nach Layout-Typ

app/
├── (with-nav)/            # Seiten mit Top-Navigation
│   ├── layout.tsx
│   ├── page.tsx
│   ├── about/page.tsx
│   └── products/page.tsx
├── (fullscreen)/          # Vollbild (ohne Navigation)
│   ├── layout.tsx
│   └── video/[id]/page.tsx
└── (auth)/                # Auth (schlichtes Layout)
    ├── layout.tsx
    ├── login/page.tsx
    └── register/page.tsx

Login/Register ohne Header/Footer; Video-Player fullscreen – jeweils eigene Gruppe.

Wichtige Hinweise

Verschiedene Route Groups dürfen nicht dieselbe URL bedienen. (marketing)/about/page.tsx und (shop)/about/page.tsx → beide /about → Next.js-Fehler.

Lösung: Routen eindeutig planen oder Präfix nutzen, z. B. (shop)/about-us/page.tsx.

Namen aussagekräftig wählen: (marketing), (dashboard), (auth) – nicht (group1).

Nested Layouts – automatische Layout-Vererbung

Funktionsweise

Route Groups sortieren Ordner; Nested Layouts lösen Layout-Hierarchien. Admin typischerweise:

  • Ebene 1: Topbar + Sidebar (alle Admin-Seiten)
  • Ebene 2: Tabs im Benutzermodul (aktiv / gesperrt)
  • Ebene 3: Seiteninhalt

layout.tsx auf jeder Ebene – automatische Verschachtelung:

app/(dashboard)/
├── layout.tsx              # Ebene 1: Topbar + Sidebar
├── users/
│   ├── layout.tsx          # Ebene 2: Benutzer-Tabs
│   ├── active/page.tsx     # /users/active
│   └── blocked/page.tsx    # /users/blocked
└── orders/
    ├── layout.tsx          # Ebene 2: Bestell-Tabs
    ├── pending/page.tsx
    └── completed/page.tsx

Bei /users/active:

DashboardLayout (Ebene 1)
  └─ UsersLayout (Ebene 2)
      └─ ActiveUsersPage (Seite)

Code:

// app/(dashboard)/layout.tsx - Ebene 1
export default function DashboardLayout({
  children
}: {
  children: React.ReactNode
}) {
  return (
    <div className="dashboard-container">
      <TopBar />
      <div className="content-area">
        <Sidebar />
        <main>{children}</main>
      </div>
    </div>
  )
}

// app/(dashboard)/users/layout.tsx - Ebene 2
export default function UsersLayout({
  children
}: {
  children: React.ReactNode
}) {
  return (
    <div className="users-section">
      <div className="tabs">
        <Link href="/users/active">Aktive Benutzer</Link>
        <Link href="/users/blocked">Gesperrte Benutzer</Link>
      </div>
      {children}
    </div>
  )
}

// app/(dashboard)/users/active/page.tsx
export default function ActiveUsersPage() {
  return <div>Aktive Benutzerliste...</div>
}

Kein manueller Layout-Import in der Seite – Next.js verschachtelt automatisch.

Partial Rendering als Performance-Vorteil

Beim Wechsel von „Aktiv“ zu „Gesperrt“:

  • Ebene-1-Layout (Topbar, Sidebar) nicht neu gerendert
  • Ebene-2-Layout (Tabs) nicht neu gerendert
  • Nur Seiteninhalt neu geladen

Ergebnis: schnellere Navigation, Client-State in Layouts (Sidebar-Suche, Scroll) bleibt erhalten.

Praxis: mehrstufige Navigation

app/(dashboard)/
├── layout.tsx              # Ebene 1
├── users/
│   ├── layout.tsx          # Ebene 2
│   ├── active/page.tsx     # Ebene 3
│   └── blocked/page.tsx
└── orders/
    ├── layout.tsx
    ├── pending/page.tsx
    └── completed/page.tsx

Verzeichnis spiegelt UI-Hierarchie – Code bleibt nachvollziehbar.

Performance-Tipps

Layouts sind standardmäßig Server Components. Interaktive Teile (Suche, Dropdown) als Client Components auslagern:

// app/(dashboard)/layout.tsx - Server Component
import SearchBar from '@/components/SearchBar' // Client Component

export default function DashboardLayout({ children }) {
  return (
    <div>
      <SearchBar />
      <main>{children}</main>
    </div>
  )
}

// components/SearchBar.tsx
'use client'
import { useState } from 'react'

export default function SearchBar() {
  const [query, setQuery] = useState('')
  // ... Interaktionslogik
}

Pro Layout-Ebene optional loading.tsx für granulare Ladezustände:

app/(dashboard)/
├── layout.tsx
├── loading.tsx
└── users/
    ├── layout.tsx
    ├── loading.tsx
    └── active/
        ├── page.tsx
        └── loading.tsx

Parallel Routes – mehrere Seiten gleichzeitig rendern

Welches Problem lösen sie?

Dashboard mit unabhängigen Modulen (Analytics, Team, Benachrichtigungen) – unterschiedliche Ladezeiten. Alles in einer page.tsx: ein langsames Modul blockiert die ganze Seite.

Parallel Routes teilen in Slots (@-Ordner), jeder mit eigenem loading/error, parallelem Laden.

Grundsyntax

app/dashboard/
├── layout.tsx
├── @analytics/page.tsx
├── @team/page.tsx
├── @notifications/page.tsx
└── page.tsx

Im Layout als Props:

// app/dashboard/layout.tsx
export default function DashboardLayout({
  children,
  analytics,
  team,
  notifications,
}: {
  children: React.ReactNode
  analytics: React.ReactNode
  team: React.ReactNode
  notifications: React.ReactNode
}) {
  return (
    <div className="dashboard-grid">
      <div className="main-content">{children}</div>
      <div className="top-panels">
        <div className="panel">{analytics}</div>
        <div className="panel">{team}</div>
      </div>
      <div className="bottom-panel">{notifications}</div>
    </div>
  )
}

Jeder Slot mit eigenem loading/error:

app/dashboard/
├── @analytics/
│   ├── page.tsx
│   ├── loading.tsx
│   └── error.tsx
├── @team/
│   ├── page.tsx
│   ├── loading.tsx
│   └── error.tsx
└── @notifications/
    ├── page.tsx
    ├── loading.tsx
    └── error.tsx

Langsames Analytics-Modul blockiert Team und Notifications nicht.

Bedingtes Rendern

// app/dashboard/layout.tsx
import { auth } from '@/lib/auth'

export default async function DashboardLayout({
  analytics,
  team,
  notifications,
}) {
  const user = await auth()
  const isAdmin = user?.role === 'admin'

  return (
    <div className="dashboard-grid">
      <div>{analytics}</div>
      {isAdmin && <div>{team}</div>}
      <div>{notifications}</div>
    </div>
  )
}

default.tsx

Navigation von /dashboard zu /dashboard/settings ohne passenden Slot → Fehler. Lösung:

// app/dashboard/@team/default.tsx
export default function Default() {
  return null
}

Wann sinnvoll?

  • Dashboard mit unabhängigen Panels
  • A/B-Tests über Slots
  • Berechtigungsbasiertes Rendern

Einfache vertikale Inhalte ohne separate Ladezustände? Direkt in page.tsx – Parallel Routes sind Overkill.

Intercepting Routes – Modal-Routing wie bei Instagram

Das Zielbild

Feed → Bild-Klick → Modal + URL /photo/abc123. Reload: Vollseite. Geteilter Link: Vollseite, kein Modal. Schließen: zurück zum Feed.

URL teilbar, Reload sicher, Navigation flüssig – schwer mit klassischem Client-State.

Syntax

  • (.) gleichstufige Route
  • (..) eine Ebene höher
  • (..)(..) zwei Ebenen höher
  • (...) von Root
app/
├── products/
│   ├── page.tsx
│   └── (..)product/[id]/page.tsx   # Modal bei Navigation von /products
└── product/
    └── [id]/page.tsx               # Vollseite bei Direktaufruf

Client-Navigation von /products → Modal. Direkt /product/123 oder Reload → Vollseite.

Praxis: Produkt-Modal

app/
├── (shop)/
│   └── products/
│       ├── page.tsx
│       └── (..)product/[id]/page.tsx
└── product/
    └── [id]/page.tsx

Modal-Version:

// app/(shop)/products/(..)product/[id]/page.tsx
'use client'
import { useRouter } from 'next/navigation'
import Modal from '@/components/Modal'
import ProductDetail from '@/components/ProductDetail'

export default function ProductModal({
  params
}: {
  params: { id: string }
}) {
  const router = useRouter()

  return (
    <Modal onClose={() => router.back()}>
      <ProductDetail id={params.id} />
    </Modal>
  )
}

Vollseite:

// app/product/[id]/page.tsx
import ProductDetail from '@/components/ProductDetail'

export default function ProductPage({
  params
}: {
  params: { id: string }
}) {
  return (
    <div className="product-page">
      <ProductDetail id={params.id} />
    </div>
  )
}

ProductDetail wiederverwendet – unterschiedliche Container (Modal vs. Seite).

Mit Parallel Routes kombinieren

app/(shop)/products/
├── layout.tsx
├── page.tsx
├── @modal/
│   ├── (..)product/[id]/page.tsx
│   └── default.tsx

Layout:

// app/(shop)/products/layout.tsx
export default function ProductsLayout({
  children,
  modal,
}: {
  children: React.ReactNode
  modal: React.ReactNode
}) {
  return (
    <>
      {children}
      {modal}
    </>
  )
}

// app/(shop)/products/@modal/default.tsx
export default function Default() {
  return null
}

Modal und Hauptinhalt sauber getrennt.

Hinweise

  1. Nur Client-Navigation – Direkte URL-Eingabe/Reload → keine Interception.
  2. Zwei Varianten pflegen – Modal + Vollseite, Komponenten teilen wo möglich.
  3. Pfad-Matching nach Route, nicht Dateisystem – Route Groups ändern URLs nicht; (..) bezieht sich auf URL-Pfade.

Wann einsetzen?

Geeignet: Galerie, Produkt-Modal, Login-Overlay mit /login-Deep-Link.

Ungeeignet: einfache Pop-ups ohne URL-Änderung, ohne Deep-Linking.

Gesamtbeispiel – E-Commerce-Verzeichnisstruktur

Anforderungen

Frontend: Startseite, Über uns, Produktliste/-detail (Modal), Warenkorb, Checkout

Admin: Dashboard (Analytics, Team, Notifications), Benutzer, Bestellungen

Auth: Login, Register (eigenes Layout)

Zielstruktur

app/
├── layout.tsx

├── (marketing)/
│   ├── layout.tsx
│   ├── page.tsx                        # /
│   ├── about/page.tsx                  # /about
│   └── pricing/page.tsx                # /pricing

├── (shop)/
│   ├── layout.tsx
│   ├── products/
│   │   ├── layout.tsx
│   │   ├── page.tsx                    # /products
│   │   └── @modal/
│   │       ├── (..)product/[id]/page.tsx
│   │       └── default.tsx
│   ├── cart/page.tsx                   # /cart
│   └── checkout/page.tsx               # /checkout

├── product/
│   └── [id]/page.tsx                   # /product/123

├── (dashboard)/
│   ├── layout.tsx
│   ├── dashboard/
│   │   ├── layout.tsx
│   │   ├── page.tsx                    # /dashboard
│   │   ├── @analytics/
│   │   │   ├── page.tsx
│   │   │   ├── loading.tsx
│   │   │   └── default.tsx
│   │   ├── @team/
│   │   │   ├── page.tsx
│   │   │   ├── loading.tsx
│   │   │   └── default.tsx
│   │   └── @notifications/
│   │       ├── page.tsx
│   │       ├── loading.tsx
│   │       └── default.tsx
│   ├── users/
│   │   ├── layout.tsx
│   │   ├── active/page.tsx             # /users/active
│   │   └── blocked/page.tsx            # /users/blocked
│   └── orders/
│       ├── layout.tsx
│       ├── pending/page.tsx            # /orders/pending
│       └── completed/page.tsx          # /orders/completed

└── (auth)/
    ├── layout.tsx
    ├── login/page.tsx                  # /login
    └── register/page.tsx               # /register

Vergleich

DimensionFlache StrukturRoute Groups + Nested Layouts
Dateisuche100+ Dateien, Präfix-RatenNach Modul gruppiert
LayoutsManueller Import pro SeiteVererbung, eine Änderung reicht
TeamarbeitEin Ordner, viele KonflikteTeams in eigenen Groups
URLsPräfixe (dashboard-users-active)Klar (/users/active)
ModalsClient-State, Reload brichtRouting-gesteuert
PerformanceLayout bei jedem Wechsel neuPartial Rendering

Messbare Effekte

  1. Dateisuche ~50 % schneller – direkt zur richtigen Route Group.
  2. Layout-Änderungen zentral – ein (dashboard)/layout.tsx statt 20 Dateien.
  3. ~60 % weniger Git-Konflikte – Teams in getrennten Bereichen.
  4. Schnelleres Onboarding – Struktur erklärt die Architektur.

Empfehlungen

  1. Nicht alles auf einmal – ein Modul (z. B. Admin) als Pilot.
  2. Aussagekräftige Namen(marketing), (shop), (dashboard), (auth).
  3. README-Dokumentation – Route-Group-Zuständigkeiten festhalten.
  4. TypeScript-Pfad-Mapping nutzen:
// tsconfig.json
{
  "compilerOptions": {
    "paths": {
      "@/*": ["./src/*"],
      "@/components/*": ["./src/components/*"],
      "@/app/*": ["./src/app/*"]
    }
  }
}

Best Practices und Fallstricke

Route-Group-Namen

Empfohlen: (marketing), (dashboard) / (admin), (auth), (team-xxx), (feature-xxx)

Vermeiden: (group1), (temp), zu lange Namen wie (marketing-and-sales-pages)

Routing-Konflikte vermeiden

❌ Fehler:
app/
├── (marketing)/about/page.tsx  # URL: /about
└── (shop)/about/page.tsx       # URL: /about – Konflikt!

Lösungen: Routen vorab planen, Präfixe (/about-us vs. /about-product), Verzeichnisebenen anpassen.

Parallel Routes – Entscheidungshilfe

Ja: unabhängige Dashboard-Panels, separate Ladezustände, Berechtigungs-Rendering, A/B-Tests

Nein: einfache vertikale Anordnung, statische Bereiche

Im Zweifel: Route Groups + Nested Layouts reichen meist.

Grenzen von Intercepting Routes

  • Nur bei Client-Navigation
  • Zwei Varianten (Modal + Vollseite)
  • Pfad-Matching auf URL-Basis – Route Groups verwirren leicht

Ohne URL-Änderung oder Deep-Link: normales Client-Modal.

Performance

  1. Layouts als Server Components belassen
  2. loading.tsx pro Ebene
  3. Suspense gezielt einsetzen
  4. Nicht mehr als ~4 Layout-Ebenen verschachteln

Migrationsstrategie (Pages → App Router)

  1. Inkrementellapp/ und pages/ parallel
  2. Zuerst Layouts – Route Groups + Nested Layouts
  3. DatenabrufgetServerSidePropsfetch, getStaticProps → Server Components
  4. RoutengetStaticPathsgenerateStaticParams
  5. Feature Flags für schrittweisen Rollout

Team-Zusammenarbeit

  1. Verzeichnis-Konvention in README/Wiki
  2. PR-Review: Konflikte, Layout-Verschachtelung
  3. ESLint-Regeln für Route-Group-Namen
  4. Regelmäßiges Aufräumen veralteter Routen

Debugging

  1. React DevTools – Komponentenbaum prüfen
  2. console.log in Layouts – unnötige Re-Renders erkennen
  3. Network-Tab – Server vs. Client Requests
  4. Next.js-Terminal – Konflikt- und Layout-Warnungen

Fazit

120 Ordner unter app/, fünf Minuten Suche – klingt vertraut? Vier App-Router-Features helfen:

Route Groups gruppieren nach Business und Team, ohne lange URLs.

Nested Layouts vererben Layouts automatisch – eine Datei ändern, alle Unterseiten aktualisiert.

Parallel Routes rendern unabhängige Module mit eigenem Loading/Error – ideal fürs Dashboard.

Intercepting Routes liefern Instagram-ähnliche Modals: teilbare URL, sicherer Reload, flüssige Navigation.

Starten Sie klein: ein Modul refactoren, validieren, dann ausrollen. Inkrementell statt Big-Bang – leichteres Rollback bei Problemen.

Die obige E-Commerce-Struktur können Sie direkt als Vorlage nutzen. Viel Erfolg mit einem aufgeräumten Next.js-Projekt!

Vollständiger Refactoring-Workflow für große Next.js-Verzeichnisstrukturen

Chaotische Verzeichnisstrukturen mit Route Groups, Nested Layouts, Parallel Routes und Intercepting Routes neu organisieren

⏱️ Estimated time: 8 hr

  1. 1

    Step 1: Bestehende Verzeichnisstruktur analysieren

    Aktuelle Probleme bewerten:
    • Anzahl Ordner zählen (ab 50 empfiehlt sich Refactoring)
    • Routing-Konflikte identifizieren
    • Doppelten Layout-Code finden
    • Team-Schmerzpunkte dokumentieren

    Funktionsbereiche erkennen:
    • Marketing-Seiten (Startseite, Über uns, Preise)
    • Shop-Seiten (Produkte, Warenkorb, Bestellungen)
    • Admin-Bereich (Benutzer, Bestellungen, Einstellungen)
  2. 2

    Step 2: Route Groups für Funktionsbereiche anlegen

    Mit Klammern Route Groups erstellen:
    • (marketing): Marketing-Seiten
    • (shop): Shop-Funktionen
    • (dashboard): Admin-Bereich

    Hinweise:
    • Route-Group-Namen beeinflussen die URL nicht
    • Dieselbe URL darf nicht in mehreren Groups vorkommen
    • Jede Route Group kann ein eigenes layout.js haben
  3. 3

    Step 3: Nested-Layout-Hierarchie entwerfen

    Nach UI-Hierarchie planen:
    • Ebene 1: app/layout.js (site-weit)
    • Ebene 2: Bereichs-layout.js (z. B. shop/layout.js)
    • Ebene 3: Detail-layout.js (z. B. shop/products/[id]/layout.js)

    Umsetzung:
    • Jede Ebene nur eigene UI-Elemente hinzufügen
    • Kind-Layouts erben automatisch vom Eltern-Layout
    • Beim Seitenwechsel wird layout nicht neu gerendert
  4. 4

    Step 4: Parallel Routes implementieren (falls nötig)

    Slots mit @ anlegen:
    • @modal: Modal-Slot
    • @sales, @orders: unabhängige Dashboard-Module

    In layout.js empfangen:
    • export default function Layout({ children, modal })
    • Im JSX rendern: {modal}

    Jeder Slot kann eigenes loading.js und error.js haben
  5. 5

    Step 5: Intercepting Routes implementieren (für Modals)

    Intercepting Route anlegen:
    • Unter @modal: (.)photos/[id]/page.js
    • Parallel: photos/[id]/page.js (Vollseite)

    Syntax:
    • (.): gleichstufige Route abfangen
    • (..): Route eine Ebene höher abfangen
    • (...): von Root abfangen

    default.js mit return null ist Pflicht
  6. 6

    Step 6: Testen und validieren

    Prüfpunkte:
    • Alle Routen erreichbar?
    • Layouts korrekt verschachtelt?
    • Seitenwechsel flüssig?
    • Modals funktionieren?

    Debug-Tools:
    • React DevTools für Komponentenbaum
    • console.log für Render-Zähler
    • Network-Tab für Requests
    • Next.js-Terminal auf Warnungen prüfen

FAQ

Wann sollte ich Route Groups verwenden?
Wenn Ihr Projekt mehr als 50 Ordner hat oder verschiedene Funktionsbereiche unterschiedliche Root-Layouts brauchen. Route Groups eignen sich besonders für Multi-Team-Projekte: Git-Konflikte sinken deutlich, die Verzeichnisstruktur wird übersichtlicher.
Beeinflussen Route Groups die URL?
Nein. Route Groups werden in Klammern benannt (z. B. (marketing)); Next.js ignoriert den Klammernamen. Die URL von (marketing)/about/page.js bleibt /about, nicht /marketing/about.
Beeinträchtigen Nested Layouts die Performance?
Nein – im Gegenteil. Beim Wechsel zwischen Unterrouten werden Nested Layouts nicht neu gerendert, nur die innerste page.js lädt neu. Status in Layouts (z. B. Sidebar-Scrollposition) bleibt beim Navigieren erhalten.
Was ist der Unterschied zwischen Parallel Routes und normalen Komponenten?
Parallel Routes: Jeder Slot ist ein unabhängiges Seitenfragment mit eigenem loading.js und error.js, paralleles Laden ohne gegenseitige Blockade. Normale Komponenten: Alle Daten müssen geladen sein, bevor gerendert wird – ein Fehler betrifft die ganze Seite.
Wie wähle ich die Intercepting-Route-Syntax?
(.) fängt gleichstufige Routen ab (z. B. @modal und photos unter app), (..) eine Ebene höher, (...) von Root. Im Zweifel mit (...) von Root starten und danach an die Verzeichnisstruktur anpassen.
Wie vermeide ich Routing-Konflikte?
Route Groups nach Funktion aufteilen und sicherstellen, dass dieselbe URL nicht in mehreren Groups vorkommt. Bei gleichnamigen Routen echte Verzeichnisebenen in der URL nutzen (ohne Klammern) oder eine Route umbenennen.
Wie lange dauert das Refactoring eines großen Projekts?
Je nach Größe: mittlere Projekte (50–100 Seiten) 1–2 Wochen, große Projekte etwa einen Monat. Empfehlung: Ein Modul als Pilot, Erfolg validieren, dann schrittweise ausrollen – inkrementelle Migration minimiert Risiko.

9 Min. Lesezeit · Veröffentlicht am: 18. Dez. 2025 · Aktualisiert am: 14. Juli 2026

Ähnliche Beiträge

Kommentare

Melde dich mit GitHub an, um einen Kommentar zu hinterlassen

Easton BlogEaston Blog