Incrementelle statische Regenerierung
Next.js ermöglicht es Ihnen, statische Seiten nach dem Build Ihrer Website zu erstellen oder zu aktualisieren. Incremental Static Regeneration (ISR) erlaubt die Verwendung von statischer Generierung auf Seitenbasis, ohne die gesamte Site neu bauen zu müssen. Mit ISR können Sie die Vorteile statischer Seiten beibehalten und gleichzeitig auf Millionen von Seiten skalieren.
Wichtig: Die
edge
-Runtime ist derzeit nicht mit ISR kompatibel, obwohl Siestale-while-revalidate
nutzen können, indem Sie dencache-control
-Header manuell setzen.
Um ISR zu verwenden, fügen Sie die revalidate
-Property zu getStaticProps
hinzu:
function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
// Diese Funktion wird beim Build auf der Server-Seite aufgerufen.
// Sie kann erneut aufgerufen werden, in einer serverlosen Funktion,
// wenn Revalidierung aktiviert ist und eine neue Anfrage eingeht
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts,
},
// Next.js wird versuchen, die Seite neu zu generieren:
// - Bei einer eingehenden Anfrage
// - Höchstens alle 10 Sekunden
revalidate: 10, // In Sekunden
}
}
// Diese Funktion wird beim Build auf der Server-Seite aufgerufen.
// Sie kann erneut aufgerufen werden, in einer serverlosen Funktion,
// wenn der Pfad noch nicht generiert wurde.
export async function getStaticPaths() {
const res = await fetch('https://.../posts')
const posts = await res.json()
// Pfade basierend auf Posts für Pre-Rendering ermitteln
const paths = posts.map((post) => ({
params: { id: post.id },
}))
// Nur diese Pfade werden beim Build pre-rendered.
// { fallback: 'blocking' } rendert Seiten bei Bedarf
// auf dem Server, wenn der Pfad nicht existiert.
return { paths, fallback: 'blocking' }
}
export default Blog
Wenn eine Anfrage an eine Seite gestellt wird, die beim Build pre-rendered wurde, wird zunächst die zwischengespeicherte Seite angezeigt.
- Alle weiteren Anfragen innerhalb der ersten 10 Sekunden werden ebenfalls aus dem Cache bedient und sind sofort verfügbar.
- Nach dem 10-Sekunden-Fenster wird die nächste Anfrage weiterhin die zwischengespeicherte (veraltete) Seite anzeigen
- Next.js löst eine Hintergrundgenerierung der Seite aus.
- Sobald die Seite erfolgreich generiert wurde, wird Next.js den Cache ungültig machen und die aktualisierte Seite anzeigen. Falls die Hintergrundgenerierung fehlschlägt, bleibt die alte Seite unverändert.
Wenn eine Anfrage an einen Pfad gestellt wird, der noch nicht generiert wurde, wird Next.js die Seite bei der ersten Anfrage serverseitig rendern. Zukünftige Anfragen werden die statische Datei aus dem Cache ausliefern. ISR auf Vercel persistiert den Cache global und behandelt Rollbacks.
Wichtig: Überprüfen Sie, ob Ihr Upstream-Datenanbieter Caching standardmäßig aktiviert hat. Möglicherweise müssen Sie dies deaktivieren (z.B.
useCdn: false
), da eine Revalidierung sonst keine frischen Daten abrufen kann, um den ISR-Cache zu aktualisieren. Caching kann auf einer CDN erfolgen (für einen angefragten Endpunkt), wenn dieser denCache-Control
-Header zurückgibt.
On-Demand Revalidierung
Wenn Sie eine revalidate
-Zeit von 60
festlegen, sehen alle Besucher für eine Minute dieselbe generierte Version Ihrer Website. Der einzige Weg, den Cache zu invalidieren, ist, wenn jemand die Seite nach Ablauf der Minute besucht.
Ab Version v12.2.0
unterstützt Next.js On-Demand Incremental Static Regeneration, um den Next.js-Cache manuell für eine bestimmte Seite zu leeren. Dies erleichtert die Aktualisierung Ihrer Website, wenn:
- Inhalte aus Ihrem Headless-CMS erstellt oder aktualisiert werden
- E-Commerce-Metadaten sich ändern (Preis, Beschreibung, Kategorie, Bewertungen etc.)
Innerhalb von getStaticProps
müssen Sie revalidate
nicht angeben, um On-Demand-Revalidierung zu nutzen. Wenn revalidate
weggelassen wird, verwendet Next.js den Standardwert false
(keine Revalidierung) und validiert die Seite nur bei Aufruf von revalidate()
neu.
Wichtig: Middleware wird für On-Demand-ISR-Anfragen nicht ausgeführt. Rufen Sie stattdessen
revalidate()
auf dem exakten Pfad auf, den Sie revalidieren möchten. Beispiel: Wenn Siepages/blog/[slug].js
und ein Rewrite von/post-1
->/blog/post-1
haben, müssen Sieres.revalidate('/blog/post-1')
aufrufen.
Verwendung von On-Demand Revalidierung
Erstellen Sie zunächst 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. Sie können die Route (manuell oder mit einem Webhook) mit folgender URL-Struktur aufrufen:
https://<your-site.com>/api/revalidate?secret=<token>
Fügen Sie das Geheimnis als Umgebungsvariable zu Ihrer Anwendung hinzu. Erstellen Sie dann die Revalidierungs-API-Route:
export default async function handler(req, res) {
// Geheimnis prüfen, um die Anfrage zu validieren
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
// z.B. für "/blog/[slug]" sollte dies "/blog/post-1" sein
await res.revalidate('/path-to-revalidate')
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')
}
}
Sehen Sie sich unsere Demo an, um On-Demand-Revalidierung in Aktion zu sehen und Feedback zu geben.
Testen von On-Demand ISR während der Entwicklung
Bei lokaler Ausführung mit next dev
wird getStaticProps
bei jeder Anfrage aufgerufen. Um zu überprüfen, ob Ihre On-Demand-ISR-Konfiguration korrekt ist, müssen Sie einen Produktions-Build erstellen und den Produktions-Server starten:
$ next build
$ next start
Anschließend können Sie bestätigen, dass statische Seiten erfolgreich revalidiert wurden.
Fehlerbehandlung und Revalidierung
Wenn bei der Hintergrundgenerierung ein Fehler in getStaticProps
auftritt oder Sie manuell einen Fehler werfen, wird die zuletzt erfolgreich generierte Seite weiterhin angezeigt. Bei der nächsten Anfrage wird Next.js erneut versuchen, getStaticProps
aufzurufen.
export async function getStaticProps() {
// Wenn dieser Aufruf einen unbehandelten Fehler verursacht, wird Next.js
// die aktuell angezeigte Seite nicht invalidieren und
// getStaticProps bei der nächsten Anfrage erneut aufrufen.
const res = await fetch('https://.../posts')
const posts = await res.json()
if (!res.ok) {
// Bei einem Serverfehler können Sie einen Fehler werfen,
// anstatt zurückzugeben, damit der Cache erst bei der
// nächsten erfolgreichen Anfrage aktualisiert wird.
throw new Error(`Fehler beim Abrufen der Posts, Status ${res.status}`)
}
// Bei erfolgreicher Anfrage werden die Posts zurückgegeben
// und alle 10 Sekunden revalidiert.
return {
props: {
posts,
},
revalidate: 10,
}
}
Self-Hosting mit ISR
Incremental Static Regeneration (ISR) funktioniert bei selbstgehosteten Next.js-Sites out of the box mit next start
.
Sie können diesen Ansatz verwenden, wenn Sie auf Container-Orchestratoren wie Kubernetes oder HashiCorp Nomad deployen. Standardmäßig werden generierte Assets im Speicher jedes Pods gespeichert. Das bedeutet, dass jeder Pod seine eigene Kopie der statischen Dateien hat. Veraltete Daten können angezeigt werden, bis der jeweilige Pod von einer Anfrage getroffen wird.
Um Konsistenz über alle Pods hinweg zu gewährleisten, können Sie das In-Memory-Caching deaktivieren. Dadurch wird der Next.js-Server angewiesen, nur Assets zu verwenden, die von ISR im Dateisystem generiert wurden.
Sie können ein gemeinsam genutztes Netzwerklaufwerk in Ihren Kubernetes-Pods (oder ähnlichem Setup) verwenden, um denselben Dateisystem-Cache zwischen verschiedenen Containern wiederzuverwenden. Durch die gemeinsame Nutzung derselben Einbindung wird auch der .next
-Ordner, der den next/image
-Cache enthält, geteilt und wiederverwendet.
Um In-Memory-Caching zu deaktivieren, setzen Sie isrMemoryCacheSize
in Ihrer next.config.js
auf 0
:
module.exports = {
experimental: {
// Standardwert ist 50MB
isrMemoryCacheSize: 0, // Cache-Größe in Bytes
},
}
Wichtig: Je nach Konfiguration Ihrer gemeinsamen Einbindung müssen Sie möglicherweise einen Race Condition zwischen mehreren Pods berücksichtigen, die gleichzeitig versuchen, den Cache zu aktualisieren.
Versionsverlauf
Version | Änderungen |
---|---|
v12.2.0 | On-Demand ISR ist stabil |
v12.1.0 | On-Demand ISR hinzugefügt (beta). |
v12.0.0 | Bot-aware ISR Fallback hinzugefügt. |
v9.5.0 | Base Path hinzugefügt. |
getServerSideProps
Daten bei jeder Anfrage mit `getServerSideProps` abrufen
Client-seitiges Datenabrufen (Client-side Fetching)
Erfahren Sie mehr über client-seitiges Datenabrufen und die Verwendung von SWR, einer React Hook-Bibliothek für Datenabruf mit Caching, Revalidierung, Fokus-Tracking, Intervall-Abruf und mehr.