Deutsch

Entdecken Sie das transformative, dateibasierte Routing-System im App Directory von Next.js, das eine verbesserte Organisation, Leistung und Entwicklererfahrung für moderne Webanwendungen bietet.

Next.js App Directory: Eine Revolution im dateibasierten Routing

Next.js hat die Grenzen der Webentwicklung kontinuierlich erweitert und Entwicklern leistungsstarke Werkzeuge und Funktionen zur Verfügung gestellt, um performante, skalierbare und benutzerfreundliche Anwendungen zu erstellen. Die Einführung des App Directory stellt einen bedeutenden Fortschritt dar, insbesondere durch seinen innovativen Ansatz beim dateibasierten Routing. Dieser Artikel befasst sich eingehend mit dem Routing-Mechanismus des App Directory und untersucht seine Vorteile, Schlüsselkonzepte und praktischen Auswirkungen auf die Erstellung moderner Webanwendungen mit Next.js.

Die Evolution des Routings in Next.js verstehen

Vor dem App Directory verließ sich Next.js für das Routing auf das Pages Directory. Obwohl dieser Ansatz effektiv war, hatte er gewisse Einschränkungen. Das Pages Directory verwendete ein einfaches dateibasiertes Routing-System, bei dem jede Datei im `pages`-Verzeichnis einer Route entsprach. Zum Beispiel würde `pages/about.js` der Route `/about` zugeordnet.

Obwohl unkompliziert, fehlte dem Pages Directory die integrierte Unterstützung für komplexe Layouts, Datenabrufstrategien und serverseitige Rendering-Muster, was oft erforderte, dass Entwickler diese Funktionen manuell implementierten. Darüber hinaus konnte die enge Kopplung von Datenabruf und Komponenten-Rendering manchmal zu Leistungsengpässen führen.

Das App Directory behebt diese Einschränkungen durch die Einführung eines flexibleren und leistungsfähigeren Routing-Systems, das auf React Server Components, Layouts und anderen fortschrittlichen Funktionen aufbaut. Es geht über eine einfache Datei-zu-Route-Zuordnung hinaus und bietet einen deklarativeren und zusammensetzbareren Ansatz zur Definition von Anwendungsrouten und Layouts.

Einführung in das App Directory: Ein neues Paradigma für das Routing

Das App Directory, das sich im Stammverzeichnis Ihres Next.js-Projekts im Ordner `app` befindet, führt einen grundlegend anderen Ansatz für das Routing ein. Anstatt Dateien direkt Routen zuzuordnen, verwendet das App Directory ein konventionsbasiertes System, bei dem die Struktur von Verzeichnissen und speziellen Dateien die Routen der Anwendung bestimmt.

Dieser Ansatz bietet mehrere entscheidende Vorteile:

Schlüsselkonzepte im Routing-System des App Directory

Um das Routing-System des App Directory effektiv zu nutzen, ist es unerlässlich, die Schlüsselkonzepte zu verstehen, die seiner Funktionalität zugrunde liegen:

1. Routensegmente und Ordner

Jeder Ordner innerhalb des `app`-Verzeichnisses repräsentiert ein Routensegment. Der Name des Ordners entspricht dem Pfadsegment in der URL. Zum Beispiel würde eine Ordnerstruktur `app/blog/posts` der Route `/blog/posts` zugeordnet.

Betrachten Sie diese Struktur:

app/
  blog/
    posts/
      page.js

Diese Struktur definiert eine Route unter `/blog/posts`. Die Datei `page.js` im Ordner `posts` ist die Routensegment-Komponente, die den Inhalt für diese Route rendert.

2. Die Datei `page.js`: Rendern von Routeninhalten

Die Datei page.js (oder page.tsx für TypeScript) ist eine spezielle Datei, die den Inhalt definiert, der für ein bestimmtes Routensegment gerendert werden soll. Sie ist der Einstiegspunkt für diese Route. Diese Datei muss eine React-Komponente als Standardexport exportieren.

Beispiel:

// app/blog/posts/page.js

export default function PostsPage() {
  return (
    <div>
      <h1>Blogbeiträge</h1>
      <p>Hier wird eine Liste von Blogbeiträgen angezeigt.</p>
    </div>
  );
}

3. Layouts: Definieren gemeinsamer Benutzeroberflächen

Layouts ermöglichen es Ihnen, eine Benutzeroberfläche zu definieren, die über mehrere Seiten oder Routensegmente hinweg geteilt wird. Ein Layout kann Elemente wie Kopfzeilen, Fußzeilen, Seitenleisten oder andere Komponenten enthalten, die in einem Abschnitt Ihrer Anwendung konsistent sein sollen. Layouts werden mit der Datei `layout.js` (oder `layout.tsx`) definiert.

Layouts sind verschachtelt. Das bedeutet, dass das Root-Layout (`app/layout.js`) die gesamte Anwendung umschließt und verschachtelte Layouts bestimmte Routensegmente umschließen. Beim Navigieren zwischen Routen, die ein gemeinsames Layout verwenden, behält Next.js den Zustand des Layouts bei und vermeidet ein erneutes Rendern, was zu einer verbesserten Leistung und einem flüssigeren Benutzererlebnis führt.

Beispiel:

// app/layout.js

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <header>
          <nav>
            <a href="/">Startseite</a> |
            <a href="/blog">Blog</a>
          </nav>
        </header>
        <main>{children}</main>
        <footer>
          <p>Copyright 2023</p>
        </footer>
      </body>
    </html>
  );
}

In diesem Beispiel definiert das `RootLayout` die grundlegende HTML-Struktur, Kopfzeile, Fußzeile und Navigation für die gesamte Anwendung. Jede Seite, die innerhalb des `app`-Verzeichnisses gerendert wird, wird von diesem Layout umschlossen.

4. Templates: Zustand bei Routenübergängen

Ähnlich wie Layouts umschließen auch Templates untergeordnete Routen. Im Gegensatz zu Layouts erstellen Templates jedoch für jede untergeordnete Route eine neue Komponenteninstanz. Das bedeutet, dass der Zustand des Templates beim Navigieren zwischen Routen innerhalb des Templates nicht erhalten bleibt. Templates sind nützlich für Szenarien, in denen Sie den Zustand bei Routenübergängen zurücksetzen oder neu initialisieren müssen. Verwenden Sie `template.js` (oder `template.tsx`), um Templates zu erstellen.

5. Routengruppen: Routen ohne URL-Segmente organisieren

Routengruppen ermöglichen es Ihnen, Ihre Routen innerhalb des App Directory zu organisieren, ohne die URL-Struktur zu beeinflussen. Routengruppen werden definiert, indem Ordnernamen in Klammern gesetzt werden, z. B. `(group-name)`. Diese Klammern weisen Next.js an, den Ordner als logischen Gruppierungsmechanismus und nicht als Routensegment zu behandeln.

Dies ist besonders nützlich für die Organisation großer Anwendungen mit vielen Routen. Sie könnten beispielsweise Routengruppen verwenden, um verschiedene Bereiche Ihrer Anwendung zu trennen, wie `(marketing)` und `(app)`. Diese Gruppen beeinflussen nur die Dateistruktur, nicht die URL-Pfade.

Beispiel:

app/
  (marketing)/
    home/
      page.js  // Erreichbar unter /home
    about/
      page.js  // Erreichbar unter /about
  (app)/
    dashboard/
      page.js  // Erreichbar unter /dashboard

6. Dynamische Routen: Umgang mit variablen Segmenten

Dynamische Routen ermöglichen es Ihnen, Routen mit variablen Segmenten zu erstellen. Dies ist nützlich für Szenarien, in denen Sie Routen basierend auf Daten generieren müssen, wie z. B. Blogbeiträge, Produktseiten oder Benutzerprofile. Dynamische Routensegmente werden definiert, indem der Segmentname in eckige Klammern gesetzt wird, z. B. `[id]`. Das `id` repräsentiert einen Parameter, auf den innerhalb der `page.js`-Komponente zugegriffen werden kann.

Beispiel:

app/
  blog/
    [slug]/
      page.js

In diesem Beispiel ist `[slug]` ein dynamisches Routensegment. Eine URL wie `/blog/mein-erster-beitrag` würde dieser Route entsprechen, und der `slug`-Parameter würde auf `mein-erster-beitrag` gesetzt. Sie können auf den `slug`-Parameter innerhalb der `page.js`-Komponente über die `params`-Prop zugreifen.

// app/blog/[slug]/page.js

export default function BlogPost({ params }) {
  const { slug } = params;
  return (
    <div>
      <h1>Blogbeitrag: {slug}</h1>
      <p>Inhalt des Blogbeitrags mit dem Slug: {slug}</p>
    </div>
  );
}

Sie müssen die möglichen Werte für diese dynamischen Routen generieren. Next.js stellt die Funktion `generateStaticParams` für die statische Seitengenerierung (SSG) und das serverseitige Rendering (SSR) bereit. Mit dieser Funktion können Sie angeben, welche dynamischen Routen zur Build-Zeit vorgerendert werden sollen.

// app/blog/[slug]/page.js

export async function generateStaticParams() {
  const posts = [
    { slug: 'mein-erster-beitrag' },
    { slug: 'mein-zweiter-beitrag' },
  ];

  return posts.map((post) => ({ slug: post.slug }));
}

export default function BlogPost({ params }) {
  const { slug } = params;
  return (
    <div>
      <h1>Blogbeitrag: {slug}</h1>
      <p>Inhalt des Blogbeitrags mit dem Slug: {slug}</p>
    </div>
  );
}

7. Catch-All-Segmente: Umgang mit unbekannten Routen

Catch-All-Segmente sind eine Art dynamischer Route, die es Ihnen ermöglicht, eine beliebige Anzahl von Segmenten in einer URL abzugleichen. Sie werden definiert, indem dem Segmentnamen drei Punkte vorangestellt werden, z. B. `[...path]`. Catch-All-Segmente sind nützlich für die Erstellung flexibler Routen, die eine Vielzahl von URL-Strukturen verarbeiten können.

Beispiel:

app/
  docs/
    [...path]/
      page.js

In diesem Beispiel ist `[...path]` ein Catch-All-Segment. URLs wie `/docs/einfuehrung`, `/docs/api/referenz` und `/docs/beispiele/grundlagen` würden alle dieser Route entsprechen. Der `path`-Parameter wäre ein Array, das die abgeglichenen Segmente enthält.

// app/docs/[...path]/page.js

export default function DocsPage({ params }) {
  const { path } = params;
  return (
    <div>
      <h1>Dokumentation</h1>
      <p>Pfad: {path.join('/')}</p>
    </div>
  );
}

8. Parallele Routen: Gleichzeitiges Rendern mehrerer Seiten

Parallele Routen ermöglichen es Ihnen, mehrere Seiten gleichzeitig innerhalb desselben Layouts zu rendern. Dies ist besonders nützlich für die Erstellung komplexer Benutzeroberflächenmuster, wie z. B. Dashboards mit mehreren Panels oder modale Dialoge, die über der aktuellen Seite erscheinen. Parallele Routen werden mit dem `@`-Symbol definiert, z. B. `@children`, `@modal`. Sie können direkt in der URL angegeben oder über den `useRouter`-Hook navigiert werden.

Beispiel:

app/
  @children/
    page.js // Rendert den Hauptinhalt
  @modal/
    login/
      page.js // Rendert das Anmelde-Modal

Um parallele Routen anzuzeigen, verwenden Sie die ``-Komponente.

9. Intercepting Routes: Erstellen anspruchsvoller UI-Übergänge

Intercepting Routes (abfangende Routen) ermöglichen es Ihnen, eine Route aus einem anderen Teil Ihrer Anwendung im Kontext der aktuellen Route zu laden. Dies kann verwendet werden, um anspruchsvolle UI-Übergänge zu erstellen, wie z. B. die Anzeige eines modalen Dialogs beim Klicken auf einen Link, ohne von der aktuellen Seite wegzunavigieren. Sie werden mit der `(...)`-Syntax definiert.

Datenabruf im App Directory

Das App Directory führt neue und verbesserte Methoden zum Abrufen von Daten ein, die React Server Components und die `fetch`-API mit integrierten Caching- und Revalidierungsfunktionen nutzen. Dies führt zu einer besseren Leistung und einem optimierten Entwicklungserlebnis. Sowohl Server- als auch Client-Komponenten können Daten abrufen, aber die Strategie unterscheidet sich.

1. Datenabruf in Server Components

Server Components, der Standard im App Directory, können Daten direkt aus Datenbanken oder APIs abrufen. Dies geschieht innerhalb der Komponentenfunktion vor dem Rendern. Da Server Components auf dem Server ausgeführt werden, können Sie geheime Schlüssel und Anmeldeinformationen sicher einbinden, ohne sie dem Client preiszugeben. Die `fetch`-API wird automatisch memoisiert, was bedeutet, dass identische Datenanfragen dedupliziert werden, was die Leistung weiter verbessert.

// app/page.js

async function getData() {
  const res = await fetch('https://jsonplaceholder.typicode.com/todos/1');
  // Der Rückgabewert wird *nicht* serialisiert
  // Sie können Date, Map, Set usw. zurückgeben.

  if (!res.ok) {
    // Dies aktiviert die nächstgelegene `error.js` Error Boundary
    throw new Error('Fehler beim Abrufen der Daten');
  }

  return res.json();
}

export default async function Page() {
  const data = await getData();

  return <div>{data.title}</div>;
}

2. Datenabruf in Client Components

Client Components, gekennzeichnet durch die 'use client'-Direktive am Anfang der Datei, werden im Browser des Benutzers ausgeführt. Der Datenabruf in Client Components beinhaltet typischerweise die Verwendung des `useEffect`-Hooks und einer Bibliothek wie `axios` oder der `fetch`-API. Server Actions bieten eine sichere Möglichkeit, Serverdaten von Client-Komponenten aus zu ändern. Dies bietet eine sichere Methode für Client-Komponenten, mit Daten auf dem Server zu interagieren, ohne API-Endpunkte direkt freizulegen.

// app/components/ClientComponent.js
'use client';

import { useState, useEffect } from 'react';

export default function ClientComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    async function fetchData() {
      const res = await fetch('https://jsonplaceholder.typicode.com/todos/1');
      const data = await res.json();
      setData(data);
    }

    fetchData();
  }, []);

  if (!data) {
    return <div>Wird geladen...</div>;
  }

  return <div>{data.title}</div>;
}

SEO-Überlegungen mit dem App Directory

Der Server-First-Ansatz des App Directory bietet erhebliche Vorteile für die SEO. Da Inhalte auf dem Server gerendert werden, können Suchmaschinen-Crawler den Seiteninhalt leicht zugreifen und indizieren. Hier sind einige wichtige SEO-Überlegungen:

Vorteile der Verwendung des Routing-Systems des App Directory

Das Routing-System des App Directory bietet eine Vielzahl von Vorteilen, die den Entwicklungsprozess verbessern, die Anwendungsleistung steigern und zu einem besseren Benutzererlebnis beitragen. Lassen Sie uns diese Vorteile genauer betrachten:

Praktische Beispiele für das App Directory Routing in Aktion

Um die Leistungsfähigkeit und Flexibilität des Routing-Systems des App Directory zu veranschaulichen, betrachten wir einige praktische Beispiele:

1. Erstellen eines einfachen Blogs mit dynamischen Routen

Stellen Sie sich eine Blog-Anwendung vor, bei der jeder Blogbeitrag seine eigene eindeutige URL hat, die auf seinem Slug basiert. Mit dem App Directory kann dies einfach mit dynamischen Routen implementiert werden:

``` app/ blog/ [slug]/ page.js ```

Das `[slug]`-Verzeichnis stellt ein dynamisches Routensegment dar, das jeder URL unter dem `/blog/`-Pfad entspricht. Die `page.js`-Datei innerhalb des `[slug]`-Verzeichnisses rendert den Inhalt für den entsprechenden Blogbeitrag.

```javascript // app/blog/[slug]/page.js export async function generateStaticParams() { // Alle Blogbeiträge aus der Datenbank oder API abrufen const posts = await fetchPosts(); // Die Beiträge auf ein Array von Slug-Parametern abbilden return posts.map((post) => ({ slug: post.slug })); } export default async function BlogPost({ params }) { const { slug } = params; // Den Blogbeitrag mit dem passenden Slug abrufen const post = await fetchPost(slug); if (!post) { return <div>Beitrag nicht gefunden</div>; } return ( <article> <h1>{post.title}</h1> <p>{post.content}</p> </article> ); } ```

Dieses Beispiel zeigt, wie man dynamische Routen verwendet, um auf einfache und effiziente Weise individuelle Seiten für jeden Blogbeitrag zu erstellen.

2. Implementierung eines modalen Dialogs mit Intercepting Routes

Angenommen, Sie möchten einen modalen Dialog implementieren, der erscheint, wenn ein Benutzer auf einen Link klickt, ohne von der aktuellen Seite wegzunavigieren. Dies kann mit Intercepting Routes erreicht werden:

``` app/ (.)photos/ [id]/ @modal/ page.js page.js ```

Hier fängt `(.)photos/[id]/@modal/page.js` Anfragen ab, die von der aktuellen Seite an `photos/[id]` gehen. Wenn ein Benutzer auf einen Link zu einem bestimmten Foto klickt, erscheint der modale Dialog über der aktuellen Seite, anstatt zu einer neuen Seite zu navigieren.

3. Erstellen eines Dashboard-Layouts mit parallelen Routen

Stellen Sie sich vor, Sie erstellen eine Dashboard-Anwendung mit mehreren Panels, die gleichzeitig gerendert werden müssen. Parallele Routen können verwendet werden, um dieses Layout zu erreichen:

``` app/ @analytics/ page.js // Analytics-Dashboard @settings/ page.js // Einstellungs-Panel page.js // Haupt-Dashboard-Layout ```

In dieser Struktur repräsentieren `@analytics` und `@settings` parallele Routen, die innerhalb des Haupt-Dashboard-Layouts gerendert werden. Jede parallele Route hat ihre eigene page.js-Datei, die den Inhalt für dieses Panel definiert. Das Layout kann entscheiden, wo diese mit der <Slot>-Komponente platziert werden.

Migration vom Pages Directory zum App Directory

Die Migration einer bestehenden Next.js-Anwendung vom Pages Directory zum App Directory erfordert sorgfältige Planung und Ausführung. Obwohl das App Directory erhebliche Vorteile bietet, führt es auch neue Konzepte und Muster ein, die Entwickler verstehen müssen. Hier ist eine schrittweise Anleitung, die Sie durch den Migrationsprozess führt:

  1. Verstehen Sie die Hauptunterschiede: Bevor Sie mit der Migration beginnen, stellen Sie sicher, dass Sie die Hauptunterschiede zwischen dem Pages Directory und dem App Directory vollständig verstehen, einschließlich des Routing-Systems, des Datenabrufs und der Komponentenarchitektur.
  2. Erstellen Sie ein `app`-Verzeichnis: Erstellen Sie ein neues Verzeichnis namens `app` im Stammverzeichnis Ihres Next.js-Projekts. Dieses Verzeichnis wird alle Komponenten und Routen enthalten, die Teil des App Directory sind.
  3. Migrieren Sie Routen schrittweise: Beginnen Sie damit, Routen inkrementell, eine nach der anderen, zu migrieren. Dies ermöglicht es Ihnen, jede Route einzeln zu testen und zu debuggen, wodurch das Risiko der Einführung von Fehlern minimiert wird.
  4. Konvertieren Sie Komponenten in Server Components: Konvertieren Sie Ihre vorhandenen React-Komponenten nach Möglichkeit in Server Components. Dies verbessert die Leistung und reduziert die Menge an JavaScript, die im Browser heruntergeladen und ausgeführt werden muss.
  5. Aktualisieren Sie die Datenabruflogik: Aktualisieren Sie Ihre Datenabruflogik, um die integrierten Datenabruffunktionen des App Directory zu nutzen. Dies kann das Verschieben von Datenabrufcode von Client Components zu Server Components beinhalten.
  6. Implementieren Sie Layouts und Templates: Implementieren Sie Layouts und Templates, um gemeinsame UI-Elemente zu definieren, die über mehrere Seiten hinweg konsistent sind.
  7. Testen Sie gründlich: Testen Sie jede migrierte Route gründlich, um sicherzustellen, dass sie korrekt funktioniert und keine Regressionen auftreten.
  8. Entfernen Sie das `pages`-Verzeichnis: Sobald alle Routen migriert sind, können Sie das `/pages`-Verzeichnis entfernen.

Fazit

Das Next.js App Directory stellt eine bedeutende Weiterentwicklung im dateibasierten Routing dar und bietet Entwicklern eine organisiertere, leistungsfähigere und flexiblere Möglichkeit, moderne Webanwendungen zu erstellen. Durch das Verständnis der Schlüsselkonzepte und die Nutzung der neuen Funktionen können Entwickler das App Directory nutzen, um außergewöhnliche Benutzererlebnisse zu schaffen und eine höhere Produktivität zu erzielen. Die Zukunft der Next.js-Entwicklung liegt im App Directory, und seine Übernahme ist ein strategischer Schritt für die Erstellung von Spitzen-Webanwendungen. Es ist ein leistungsstarkes Werkzeug für Entwickler weltweit.

Während sich das Next.js-Ökosystem weiterentwickelt, ist das App Directory auf dem besten Weg, zum Standard für die Erstellung robuster, skalierbarer und leistungsfähiger Webanwendungen zu werden. Nehmen Sie die Veränderung an, erkunden Sie die Möglichkeiten und entfalten Sie das volle Potenzial von Next.js!

Next.js App Directory: Eine Revolution im dateibasierten Routing | MLOG