Einführung/Leitfäden/ISR

Implementierung von Incremental Static Regeneration (ISR)

Beispiele

Incremental Static Regeneration (ISR) ermöglicht Ihnen:

  • Statische Inhalte ohne Neubau der gesamten Website zu aktualisieren
  • Serverlast zu reduzieren durch Ausliefern vorgerenderter, statischer Seiten für die meisten Anfragen
  • Sicherzustellen, dass korrekte cache-control-Header automatisch zu Seiten hinzugefügt werden
  • Große Mengen von Inhaltsseiten ohne lange next build-Zeiten zu verwalten

Hier ist ein minimales Beispiel:

import type { GetStaticPaths, GetStaticProps } from 'next'

interface Post {
  id: string
  title: string
  content: string
}

interface Props {
  post: Post
}

export const getStaticPaths: GetStaticPaths = async () => {
  const posts = await fetch('https://api.vercel.app/blog').then((res) =>
    res.json()
  )
  const paths = posts.map((post: Post) => ({
    params: { id: String(post.id) },
  }))

  // Wir werden nur diese Pfade zur Build-Zeit vorrendern.
  // { fallback: 'blocking' } wird Seiten bedarfsgerecht
  // serverseitig rendern, wenn der Pfad nicht existiert.
  return { paths, fallback: false }
}

export const getStaticProps: GetStaticProps<Props> = async ({
  params,
}: {
  params: { id: string }
}) => {
  const post = await fetch(`https://api.vercel.app/blog/${params.id}`).then(
    (res) => res.json()
  )

  return {
    props: { post },
    // Next.js wird den Cache ungültig machen, wenn eine
    // Anfrage eingeht, maximal einmal alle 60 Sekunden.
    revalidate: 60,
  }
}

export default function Page({ post }: Props) {
  return (
    <main>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </main>
  )
}

So funktioniert dieses Beispiel:

  1. Während next build werden alle bekannten Blogbeiträge generiert (in diesem Beispiel gibt es 25)
  2. Alle Anfragen an diese Seiten (z.B. /blog/1) werden zwischengespeichert und sind sofort verfügbar
  3. Nach 60 Sekunden zeigt die nächste Anfrage weiterhin die zwischengespeicherte (veraltete) Seite
  4. Der Cache wird ungültig gemacht und eine neue Version der Seite beginnt im Hintergrund zu generieren
  5. Nach erfolgreicher Generierung zeigt Next.js die aktualisierte Seite an und speichert sie im Cache
  6. Wenn /blog/26 angefragt wird, generiert Next.js diese Seite bedarfsgerecht und speichert sie im Cache

Referenz

Funktionen

Beispiele

On-Demand-Validierung mit res.revalidate()

Für eine präzisere Methode der Revalidierung können Sie res.revalidate verwenden, um eine neue Seite bedarfsgerecht von einem API-Router aus zu generieren.

Zum Beispiel kann diese API-Route unter /api/revalidate?secret=<token> aufgerufen werden, um einen bestimmten Blogbeitrag zu revalidieren. Erstellen Sie ein geheimes Token, das nur Ihrer Next.js-App bekannt ist. Dieses Geheimnis wird verwendet, um unbefugten Zugriff auf die Revalidierungs-API-Route zu verhindern.

import type { NextApiRequest, NextApiResponse } from 'next'

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  // Überprüfen des Geheimnisses, um sicherzustellen, dass dies eine gültige Anfrage ist
  if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
    return res.status(401).json({ message: 'Ungültiges Token' })
  }

  try {
    // Dies sollte der tatsächliche Pfad sein, kein umgeschriebener Pfad
    // z.B. für "/posts/[id]" sollte dies "/posts/1" sein
    await res.revalidate('/posts/1')
    return res.json({ revalidated: true })
  } catch (err) {
    // Bei einem Fehler zeigt Next.js weiterhin
    // die letzte erfolgreich generierte Seite an
    return res.status(500).send('Fehler bei der Revalidierung')
  }
}

Wenn Sie On-Demand-Revalidierung verwenden, müssen Sie keine revalidate-Zeit in getStaticProps angeben. Next.js verwendet den Standardwert false (keine Revalidierung) und revalidiert die Seite nur bedarfsgerecht, wenn res.revalidate() aufgerufen wird.

Behandlung unbehandelter Ausnahmen

Wenn ein Fehler in getStaticProps während der Hintergrundregenerierung auftritt oder Sie manuell einen Fehler werfen, wird die zuletzt erfolgreich generierte Seite weiterhin angezeigt. Bei der nächsten nachfolgenden Anfrage wird Next.js erneut versuchen, getStaticProps aufzurufen.

import type { GetStaticProps } from 'next'

interface Post {
  id: string
  title: string
  content: string
}

interface Props {
  post: Post
}

export const getStaticProps: GetStaticProps<Props> = async ({
  params,
}: {
  params: { id: string }
}) => {
  // Wenn diese Anfrage einen unbehandelten Fehler wirft, wird Next.js
  // die aktuell angezeigte Seite nicht ungültig machen und
  // getStaticProps bei der nächsten Anfrage erneut aufrufen.
  const res = await fetch(`https://api.vercel.app/blog/${params.id}`)
  const post: Post = await res.json()

  if (!res.ok) {
    // Bei einem Serverfehler sollten Sie möglicherweise
    // einen Fehler werfen statt zurückzugeben, damit der Cache nicht aktualisiert wird
    // bis zur nächsten erfolgreichen Anfrage.
    throw new Error(`Fehler beim Abrufen der Beiträge, Status ${res.status}`)
  }

  return {
    props: { post },
    // Next.js wird den Cache ungültig machen, wenn eine
    // Anfrage eingeht, maximal einmal alle 60 Sekunden.
    revalidate: 60,
  }
}

Anpassung des Cache-Speicherorts

Sie können den Cache-Speicherort von Next.js konfigurieren, wenn Sie zwischengespeicherte Seiten und Daten in dauerhaften Speicher persistieren oder den Cache über mehrere Container oder Instanzen Ihrer Next.js-Anwendung hinweg teilen möchten. Mehr erfahren.

Problembehandlung

Debuggen von zwischengespeicherten Daten in der lokalen Entwicklung

Wenn Sie die fetch-API verwenden, können Sie zusätzliche Protokollierung hinzufügen, um zu verstehen, welche Anfragen zwischengespeichert oder nicht zwischengespeichert sind. Mehr über die logging-Option erfahren.

next.config.js
module.exports = {
  logging: {
    fetches: {
      fullUrl: true,
    },
  },
}

Überprüfung des korrekten Produktionsverhaltens

Um zu überprüfen, ob Ihre Seiten in der Produktion korrekt zwischengespeichert und revalidiert werden, können Sie lokal testen, indem Sie next build und dann next start ausführen, um den Next.js-Produktionsserver zu starten.

Dadurch können Sie das ISR-Verhalten (Incremental Static Regeneration) testen, wie es in einer Produktionsumgebung funktionieren würde. Für weitere Debugging-Zwecke fügen Sie die folgende Umgebungsvariable zu Ihrer .env-Datei hinzu:

.env
NEXT_PRIVATE_DEBUG_CACHE=1

Dies führt dazu, dass der Next.js-Server ISR-Cache-Treffer und -Fehlschläge in der Konsole protokolliert. Sie können die Ausgabe untersuchen, um zu sehen, welche Seiten während next build generiert werden und wie Seiten aktualisiert werden, wenn Pfade bedarfsgesteuert aufgerufen werden.

Einschränkungen

  • ISR wird nur unterstützt, wenn die Node.js-Laufzeitumgebung (Standard) verwendet wird.
  • ISR wird nicht unterstützt, wenn ein Statischer Export erstellt wird.
  • Middleware wird nicht für bedarfsgesteuerte ISR-Anfragen ausgeführt, was bedeutet, dass Pfadumleitungen oder Logik in der Middleware nicht angewendet werden. Stellen Sie sicher, dass Sie den exakten Pfad revalidieren. Zum Beispiel /post/1 anstelle eines umgeleiteten /post-1.

Plattformunterstützung

BereitstellungsoptionUnterstützt
Node.js-ServerJa
Docker-ContainerJa
Statischer ExportNein
AdapterPlattformabhängig

Erfahren Sie, wie Sie ISR konfigurieren, wenn Sie Next.js selbst hosten.

Versionsverlauf

VersionÄnderungen
v14.1.0Benutzerdefinierter cacheHandler ist stabil.
v13.0.0App Router wird eingeführt.
v12.2.0Pages Router: On-Demand ISR ist stabil
v12.0.0Pages Router: Bot-aware ISR-Fallback hinzugefügt.
v9.5.0Pages Router: Stabiles ISR eingeführt.