Menu

Layout und Vorlagen

Die speziellen Dateien layout.js und template.js ermöglichen es Ihnen, eine Benutzeroberfläche zu erstellen, die zwischen Routen geteilt wird. Diese Seite führt Sie durch die Verwendung dieser speziellen Dateien.

Layouts

Ein Layout ist eine Benutzeroberfläche, die zwischen mehreren Routen geteilt wird. Bei der Navigation bleiben Layouts erhalten, interaktiv und werden nicht neu gerendert. Layouts können auch verschachtelt sein.

Sie können ein Layout definieren, indem Sie eine React-Komponente aus einer layout.js-Datei exportieren. Die Komponente sollte eine children-Prop akzeptieren, die während des Renderns mit einem untergeordneten Layout (falls vorhanden) oder einer Seite gefüllt wird.

Zum Beispiel wird das Layout mit den Seiten /dashboard und /dashboard/settings geteilt:

layout.js-Spezialdatei
app/dashboard/layout.tsx
TypeScript
export default function DashboardLayout({
  children, // wird eine Seite oder ein verschachteltes Layout sein
}: {
  children: React.ReactNode
}) {
  return (
    <section>
      {/* Gemeinsame UI hier einfügen, z.B. eine Kopfzeile oder Seitenleiste */}
      <nav></nav>
 
      {children}
    </section>
  )
}

Root Layout (erforderlich)

Das Root Layout wird auf oberster Ebene des app-Verzeichnisses definiert und gilt für alle Routen. Dieses Layout ist erforderlich und muss html- und body-Tags enthalten, sodass Sie das ursprüngliche HTML ändern können, das vom Server zurückgegeben wird.

app/layout.tsx
TypeScript
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        {/* Layout-UI */}
        <main>{children}</main>
      </body>
    </html>
  )
}

Verschachtelte Layouts

Standardmäßig sind Layouts in der Ordnerhierarchie verschachtelt, was bedeutet, dass sie untergeordnete Layouts über ihre children-Prop umschließen. Sie können Layouts verschachteln, indem Sie eine layout.js-Datei in bestimmten Routensegmenten (Ordnern) hinzufügen.

Um beispielsweise ein Layout für die /dashboard-Route zu erstellen, fügen Sie eine neue layout.js-Datei im dashboard-Ordner hinzu:

Verschachteltes Layout
app/dashboard/layout.tsx
TypeScript
export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return <section>{children}</section>
}

Wenn Sie die beiden obigen Layouts kombinieren, würde das Root-Layout (app/layout.js) das Dashboard-Layout (app/dashboard/layout.js) umschließen, das wiederum die Routensegmente in app/dashboard/* umschließt.

Die beiden Layouts würden wie folgt verschachtelt sein:

Verschachtelte Layouts

Hinweis:

  • .js, .jsx oder .tsx Dateierweiterungen können für Layouts verwendet werden.
  • Nur das Root-Layout kann <html>- und <body>-Tags enthalten.
  • Wenn eine layout.js- und page.js-Datei im selben Ordner definiert sind, umschließt das Layout die Seite.
  • Layouts sind standardmäßig Server-Komponenten, können aber als Client-Komponenten festgelegt werden.
  • Layouts können Daten abrufen. Weitere Informationen finden Sie im Abschnitt Datenabruf.
  • Das Übergeben von Daten zwischen einem übergeordneten Layout und seinen untergeordneten Elementen ist nicht möglich. Sie können jedoch dieselben Daten in einer Route mehrmals abrufen, und React wird die Anfragen automatisch entduplizieren, ohne die Leistung zu beeinträchtigen.
  • Layouts haben keinen Zugriff auf pathname (mehr erfahren). Importierte Client-Komponenten können jedoch den Pfadnamen mithilfe des usePathname-Hooks aufrufen.
  • Layouts haben keinen Zugriff auf die Routensegmente unterhalb ihrer selbst. Um auf alle Routensegmente zuzugreifen, können Sie useSelectedLayoutSegment oder useSelectedLayoutSegments in einer Client-Komponente verwenden.
  • Sie können Routengruppen verwenden, um bestimmte Routensegmente in gemeinsame Layouts ein- oder auszuschließen.
  • Sie können Routengruppen verwenden, um mehrere Root-Layouts zu erstellen. Ein Beispiel finden Sie hier.
  • Migration aus dem pages-Verzeichnis: Das Root-Layout ersetzt die Dateien _app.js und _document.js. Migrationsanleitung anzeigen.

Vorlagen

Vorlagen ähneln Layouts, insofern sie ein untergeordnetes Layout oder eine Seite umschließen. Im Gegensatz zu Layouts, die routenübergreifend erhalten bleiben und den Zustand beibehalten, erstellen Vorlagen bei der Navigation für ihre untergeordneten Elemente eine neue Instanz. Das bedeutet, dass bei der Navigation zwischen Routen, die eine Vorlage teilen, eine neue Instanz des untergeordneten Elements eingebunden, DOM-Elemente neu erstellt, der Zustand in Client-Komponenten nicht beibehalten und Effekte neu synchronisiert werden.

Es gibt Fälle, in denen Sie diese speziellen Verhaltensweisen benötigen, und Vorlagen wären dann eine geeignetere Option als Layouts. Zum Beispiel:

  • Um useEffect bei der Navigation neu zu synchronisieren.
  • Um den Zustand einer untergeordneten Client-Komponente bei der Navigation zurückzusetzen.

Eine Vorlage kann definiert werden, indem eine Standard-React-Komponente aus einer template.js-Datei exportiert wird. Die Komponente sollte eine children-Prop akzeptieren.

template.js-Spezialdatei
app/template.tsx
TypeScript
export default function Template({ children }: { children: React.ReactNode }) {
  return <div>{children}</div>
}

In Bezug auf die Verschachtelung wird template.js zwischen einem Layout und seinen untergeordneten Elementen gerendert. Hier ist eine vereinfachte Ausgabe:

Ausgabe
<Layout>
  {/* Beachten Sie, dass der Template ein eindeutiger Schlüssel gegeben wird. */}
  <Template key={routeParam}>{children}</Template>
</Layout>

Beispiele

Metadaten

Sie können HTML-Elemente wie title und meta im <head> mithilfe der Metadaten-APIs ändern.

Metadaten können durch Exportieren eines metadata-Objekts oder einer generateMetadata-Funktion in einer layout.js- oder page.js-Datei definiert werden.

app/page.tsx
TypeScript
import type { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: 'Next.js',
}
 
export default function Page() {
  return '...'
}

Hinweis: Sie sollten keine <head>-Tags wie <title> und <meta> manuell zu Root-Layouts hinzufügen. Verwenden Sie stattdessen die Metadata API, die fortgeschrittene Anforderungen wie Streaming und Deduplizierung von <head>-Elementen automatisch handhabt.

Weitere Informationen zu verfügbaren Metadaten-Optionen finden Sie in der API-Referenz.

Sie können den usePathname() Hook verwenden, um zu bestimmen, ob ein Navigationslink aktiv ist.

Da usePathname() ein Client-Hook ist, müssen Sie die Navigationslinks in eine Client-Komponente extrahieren, die in Ihr Layout oder Template importiert werden kann:

app/ui/nav-links.tsx
TypeScript
'use client'
 
import { usePathname } from 'next/navigation'
import Link from 'next/link'
 
export function NavLinks() {
  const pathname = usePathname()
 
  return (
    <nav>
      <Link className={`link ${pathname === '/' ? 'active' : ''}`} href="/">
        Home
      </Link>
 
      <Link
        className={`link ${pathname === '/about' ? 'active' : ''}`}
        href="/about"
      >
        About
      </Link>
    </nav>
  )
}
app/layout.tsx
TypeScript
import { NavLinks } from '@/app/ui/nav-links'
 
export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <NavLinks />
        <main>{children}</main>
      </body>
    </html>
  )
}