Draft Mode
In der Pages-Dokumentation und der Data Fetching-Dokumentation haben wir besprochen, wie Sie eine Seite zur Build-Zeit (Static Generation) mit getStaticProps
und getStaticPaths
vorrendern können.
Statische Generierung ist nützlich, wenn Ihre Seiten Daten von einem Headless CMS abrufen. Allerdings ist sie nicht ideal, wenn Sie einen Entwurf in Ihrem Headless CMS schreiben und diesen sofort auf Ihrer Seite sehen möchten. In diesem Fall möchten Sie, dass Next.js diese Seiten zur Laufzeit statt zur Build-Zeit rendert und den Entwurfsinhalt statt des veröffentlichten Inhalts abruft. Sie möchten, dass Next.js die statische Generierung nur für diesen speziellen Fall umgeht.
Next.js bietet eine Funktion namens Draft Mode, die dieses Problem löst. Hier sind die Anweisungen zur Verwendung.
Schritt 1: API-Route erstellen und aufrufen
Werfen Sie zuerst einen Blick in die API Routes-Dokumentation, wenn Sie mit Next.js API-Routen nicht vertraut sind.
Erstellen Sie zunächst die API-Route. Sie kann beliebig benannt werden, z.B. pages/api/draft.ts
.
In dieser API-Route müssen Sie setDraftMode
auf dem Response-Objekt aufrufen.
export default function handler(req, res) {
// ...
res.setDraftMode({ enable: true })
// ...
}
Dadurch wird ein Cookie gesetzt, um den Draft Mode zu aktivieren. Nachfolgende Anfragen, die diesen Cookie enthalten, lösen den Draft Mode aus und ändern das Verhalten für statisch generierte Seiten (mehr dazu später).
Sie können dies manuell testen, indem Sie eine API-Route wie unten erstellen und manuell über Ihren Browser aufrufen:
// Einfaches Beispiel zum manuellen Testen im Browser.
export default function handler(req, res) {
res.setDraftMode({ enable: true })
res.end('Draft mode is enabled')
}
Wenn Sie die Entwicklertools Ihres Browsers öffnen und /api/draft
aufrufen, werden Sie einen Set-Cookie
-Response-Header mit einem Cookie namens __prerender_bypass
bemerken.
Sicherer Zugriff aus Ihrem Headless CMS
In der Praxis möchten Sie diese API-Route sicher aus Ihrem Headless CMS aufrufen. Die genauen Schritte hängen davon ab, welches Headless CMS Sie verwenden, aber hier sind einige allgemeine Schritte.
Diese Schritte setzen voraus, dass Ihr Headless CMS das Setzen von benutzerdefinierten Draft-URLs unterstützt. Falls nicht, können Sie diese Methode trotzdem verwenden, um Ihre Draft-URLs zu sichern, müssen die Draft-URL jedoch manuell erstellen und aufrufen.
Erstens sollten Sie einen geheimen Token-String mit einem Token-Generator Ihrer Wahl erstellen. Dieses Geheimnis sollte nur Ihrer Next.js-App und Ihrem Headless CMS bekannt sein. Es verhindert, dass Personen ohne Zugriff auf Ihr CMS auf Draft-URLs zugreifen können.
Zweitens, wenn Ihr Headless CMS benutzerdefinierte Draft-URLs unterstützt, geben Sie Folgendes als Draft-URL an. Dabei wird angenommen, dass sich Ihre Draft-API-Route unter pages/api/draft.ts
befindet.
https://<your-site>/api/draft?secret=<token>&slug=<path>
<your-site>
sollte Ihre Bereitstellungsdomain sein.<token>
sollte durch den generierten geheimen Token ersetzt werden.<path>
sollte der Pfad der Seite sein, die Sie anzeigen möchten. Wenn Sie/posts/foo
anzeigen möchten, sollten Sie&slug=/posts/foo
verwenden.
Ihr Headless CMS könnte es ermöglichen, eine Variable in der Draft-URL zu verwenden, sodass <path>
dynamisch basierend auf den Daten des CMS gesetzt werden kann, z.B.: &slug=/posts/{entry.fields.slug}
Schließlich in der Draft-API-Route:
- Überprüfen Sie, ob der Secret-Token übereinstimmt und der
slug
-Parameter vorhanden ist (falls nicht, sollte die Anfrage fehlschlagen). - Rufen Sie
res.setDraftMode
auf. - Leiten Sie dann den Browser zu dem durch
slug
angegebenen Pfad um (im folgenden Beispiel wird eine 307-Weiterleitung verwendet).
export default async (req, res) => {
// Überprüfen des Secrets und der nächsten Parameter
// Dieses Geheimnis sollte nur dieser API-Route und dem CMS bekannt sein
if (req.query.secret !== 'MY_SECRET_TOKEN' || !req.query.slug) {
return res.status(401).json({ message: 'Invalid token' })
}
// Abrufen des Headless CMS, um zu prüfen, ob der angegebene `slug` existiert
// getPostBySlug würde die erforderliche Abruflogik für das Headless CMS implementieren
const post = await getPostBySlug(req.query.slug)
// Wenn der Slug nicht existiert, wird der Draft Mode nicht aktiviert
if (!post) {
return res.status(401).json({ message: 'Invalid slug' })
}
// Aktivieren des Draft Mode durch Setzen des Cookies
res.setDraftMode({ enable: true })
// Weiterleitung zum Pfad des abgerufenen Posts
// Wir leiten nicht zu req.query.slug um, da dies zu Open-Redirect-Schwachstellen führen könnte
res.redirect(post.slug)
}
Wenn dies erfolgreich ist, wird der Browser zu dem gewünschten Pfad mit dem Draft-Mode-Cookie weitergeleitet.
Schritt 2: getStaticProps
aktualisieren
Der nächste Schritt besteht darin, getStaticProps
für den Draft Mode anzupassen.
Wenn Sie eine Seite anfordern, die getStaticProps
mit dem gesetzten Cookie (über res.setDraftMode
) aufruft, wird getStaticProps
zur Laufzeit (statt zur Build-Zeit) aufgerufen.
Darüber hinaus wird es mit einem context
-Objekt aufgerufen, bei dem context.draftMode
true
ist.
export async function getStaticProps(context) {
if (context.draftMode) {
// dynamische Daten
}
}
Wir haben res.setDraftMode
in der Draft-API-Route verwendet, daher wird context.draftMode
true
sein.
Wenn Sie auch getStaticPaths
verwenden, ist context.params
ebenfalls verfügbar.
Entwurfsdaten abrufen
Sie können getStaticProps
anpassen, um basierend auf context.draftMode
unterschiedliche Daten abzurufen.
Ihr Headless CMS könnte beispielsweise einen anderen API-Endpunkt für Entwurfsposts haben. In diesem Fall können Sie die API-Endpunkt-URL wie folgt anpassen:
export async function getStaticProps(context) {
const url = context.draftMode
? 'https://draft.example.com'
: 'https://production.example.com'
const res = await fetch(url)
// ...
}
Das war's! Wenn Sie die Draft-API-Route (mit secret
und slug
) aus Ihrem Headless CMS oder manuell aufrufen, sollten Sie nun den Entwurfsinhalt sehen können. Und wenn Sie Ihren Entwurf ohne Veröffentlichung aktualisieren, sollten Sie den Entwurf einsehen können.
Setzen Sie dies als Draft-URL in Ihrem Headless CMS oder rufen Sie sie manuell auf, und Sie sollten den Entwurf sehen können.
https://<your-site>/api/draft?secret=<token>&slug=<path>
Weitere Details
Draft-Mode-Cookie löschen
Standardmäßig endet die Draft-Mode-Sitzung, wenn der Browser geschlossen wird.
Um den Draft-Mode-Cookie manuell zu löschen, erstellen Sie eine API-Route, die setDraftMode({ enable: false })
aufruft:
export default function handler(req, res) {
res.setDraftMode({ enable: false })
}
Rufen Sie dann /api/disable-draft
auf, um die API-Route auszuführen. Wenn Sie diese Route mit next/link
aufrufen, müssen Sie prefetch={false}
übergeben, um ein versehentliches Löschen des Cookies beim Prefetch zu verhindern.
Funktioniert mit getServerSideProps
Draft Mode funktioniert mit getServerSideProps
und ist als draftMode
-Schlüssel im context
-Objekt verfügbar.
Gut zu wissen: Sie sollten den
Cache-Control
-Header nicht setzen, wenn Sie Draft Mode verwenden, da er nicht umgangen werden kann. Stattdessen empfehlen wir die Verwendung von ISR.
Funktioniert mit API-Routen
API-Routen haben Zugriff auf draftMode
im Request-Objekt. Zum Beispiel:
export default function myApiRoute(req, res) {
if (req.draftMode) {
// Entwurfsdaten abrufen
}
}
Einzigartig pro next build
Bei jedem Ausführen von next build
wird ein neuer Bypass-Cookie-Wert generiert.
Dadurch wird sichergestellt, dass der Bypass-Cookie nicht erraten werden kann.
Gut zu wissen: Um Draft Mode lokal über HTTP zu testen, muss Ihr Browser Cookies von Drittanbietern und Zugriff auf den lokalen Speicher erlauben.