Menu

Seiten und Layouts

Der Pages Router basiert auf einem dateibasierten Router nach dem Konzept von Seiten.

Wenn eine Datei zum pages-Verzeichnis hinzugefügt wird, ist sie automatisch als Route verfügbar.

In Next.js ist eine Seite eine React-Komponente, die aus einer .js-, .jsx-, .ts- oder .tsx-Datei im pages-Verzeichnis exportiert wird. Jede Seite ist mit einer Route basierend auf ihrem Dateinamen verknüpft.

Beispiel: Wenn Sie pages/about.js erstellen, das eine React-Komponente wie unten exportiert, wird sie unter /about erreichbar sein.

export default function About() {
  return <div>About</div>
}

Indexrouten

Der Router leitet Dateien mit dem Namen index automatisch zur Stammverzeichnis-Route weiter.

  • pages/index.js/
  • pages/blog/index.js/blog

Verschachtelte Routen

Der Router unterstützt verschachtelte Dateien. Wenn Sie eine verschachtelte Ordnerstruktur erstellen, werden Dateien weiterhin automatisch geroutet.

  • pages/blog/first-post.js/blog/first-post
  • pages/dashboard/settings/username.js/dashboard/settings/username

Seiten mit dynamischen Routen

Next.js unterstützt Seiten mit dynamischen Routen. Wenn Sie beispielsweise eine Datei namens pages/posts/[id].js erstellen, ist sie unter posts/1, posts/2 usw. erreichbar.

Um mehr über dynamisches Routing zu erfahren, lesen Sie die Dokumentation zu dynamischen Routen.

Layout-Muster

Das React-Modell ermöglicht es uns, eine Seite in eine Reihe von Komponenten zu zerlegen. Viele dieser Komponenten werden häufig zwischen Seiten wiederverwendet. Zum Beispiel könnten Sie auf jeder Seite die gleiche Navigationsleiste und Fußzeile haben.

components/layout.js
import Navbar from './navbar'
import Footer from './footer'
 
export default function Layout({ children }) {
  return (
    <>
      <Navbar />
      <main>{children}</main>
      <Footer />
    </>
  )
}

Beispiele

Einzelnes gemeinsames Layout mit Custom App

Wenn Sie nur ein Layout für Ihre gesamte Anwendung haben, können Sie eine Custom App erstellen und Ihre Anwendung mit dem Layout umschließen. Da die <Layout /> Komponente beim Seitenwechsel wiederverwendet wird, bleibt ihr Komponentenzustand erhalten (z.B. Eingabewerte).

pages/_app.js
import Layout from '../components/layout'
 
export default function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  )
}

Seitenspezifische Layouts

Wenn Sie mehrere Layouts benötigen, können Sie Ihrer Seite eine getLayout-Eigenschaft hinzufügen, sodass Sie eine React-Komponente für das Layout zurückgeben können. Dies ermöglicht es Ihnen, das Layout seitenweise zu definieren. Da wir eine Funktion zurückgeben, können wir bei Bedarf komplexe verschachtelte Layouts erstellen.

pages/index.js
 
import Layout from '../components/layout'
import NestedLayout from '../components/nested-layout'
 
export default function Page() {
  return (
    /** Ihr Inhalt */
  )
}
 
Page.getLayout = function getLayout(page) {
  return (
    <Layout>
      <NestedLayout>{page}</NestedLayout>
    </Layout>
  )
}
pages/_app.js
export default function MyApp({ Component, pageProps }) {
  // Verwenden Sie das auf Seitenebene definierte Layout, falls verfügbar
  const getLayout = Component.getLayout ?? ((page) => page)
 
  return getLayout(<Component {...pageProps} />)
}

Beim Navigieren zwischen Seiten möchten wir den Seitenzustand (Eingabewerte, Scroll-Position usw.) für ein Single-Page-Application (SPA)-Erlebnis beibehalten.

Dieses Layout-Muster ermöglicht die Zustandserhaltung, da der React-Komponentenbaum zwischen Seitenübergängen beibehalten wird. Mit dem Komponentenbaum kann React verstehen, welche Elemente sich geändert haben, um den Zustand zu bewahren.

Hinweis: Dieser Vorgang wird Reconciliation genannt, und so versteht React, welche Elemente sich geändert haben.

Mit TypeScript

Bei Verwendung von TypeScript müssen Sie zunächst einen neuen Typ für Ihre Seiten erstellen, der eine getLayout-Funktion enthält. Anschließend müssen Sie einen neuen Typ für Ihre AppProps erstellen, der die Component-Eigenschaft überschreibt, um den zuvor erstellten Typ zu verwenden.

pages/index.tsx
TypeScript
import type { ReactElement } from 'react'
import Layout from '../components/layout'
import NestedLayout from '../components/nested-layout'
import type { NextPageWithLayout } from './_app'
 
const Page: NextPageWithLayout = () => {
  return <p>hallo welt</p>
}
 
Page.getLayout = function getLayout(page: ReactElement) {
  return (
    <Layout>
      <NestedLayout>{page}</NestedLayout>
    </Layout>
  )
}
 
export default Page
pages/_app.tsx
TypeScript
import type { ReactElement, ReactNode } from 'react'
import type { NextPage } from 'next'
import type { AppProps } from 'next/app'
 
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
  getLayout?: (page: ReactElement) => ReactNode
}
 
type AppPropsWithLayout = AppProps & {
  Component: NextPageWithLayout
}
 
export default function MyApp({ Component, pageProps }: AppPropsWithLayout) {
  // Verwenden Sie das auf Seitenebene definierte Layout, falls verfügbar
  const getLayout = Component.getLayout ?? ((page) => page)
 
  return getLayout(<Component {...pageProps} />)
}

Datenabruf

In Ihrem Layout können Sie Daten clientseitig mit useEffect oder einer Bibliothek wie SWR abrufen. Da diese Datei keine Seite ist, können Sie derzeit nicht getStaticProps oder getServerSideProps verwenden.

components/layout.js
import useSWR from 'swr'
import Navbar from './navbar'
import Footer from './footer'
 
export default function Layout({ children }) {
  const { data, error } = useSWR('/api/navigation', fetcher)
 
  if (error) return <div>Laden fehlgeschlagen</div>
  if (!data) return <div>Lädt...</div>
 
  return (
    <>
      <Navbar links={data.links} />
      <main>{children}</main>
      <Footer />
    </>
  )
}