Menu

Entwurfsmodus

In der Pages-Dokumentation und der Dokumentation zum Datenabruf haben wir besprochen, wie man eine Seite zur Bauzeit (Statische Generierung) mit getStaticProps und getStaticPaths vorrendering kann.

Statische Generierung ist nützlich, wenn Ihre Seiten Daten von einem Headless-CMS abrufen. Jedoch ist es nicht ideal, wenn Sie einen Entwurf in Ihrem Headless-CMS erstellen und diesen sofort auf Ihrer Seite sehen möchten. Sie möchten, dass Next.js diese Seiten zur Anforderungszeit anstatt zur Bauzeit rendert und den Entwurfsinhalt anstelle des veröffentlichten Inhalts abruft. Sie möchten, dass Next.js die Statische Generierung nur in diesem speziellen Fall umgeht.

Next.js bietet eine Funktion namens Entwurfsmodus, 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 für das Antwortobjekt aufrufen.

export default function handler(req, res) {
  // ...
  res.setDraftMode({ enable: true })
  // ...
}

Dies wird einen Cookie setzen, um den Entwurfsmodus zu aktivieren. Nachfolgende Anfragen, die diesen Cookie enthalten, lösen den Entwurfsmodus 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 sie manuell über Ihren Browser aufrufen:

pages/api/draft.ts
// einfaches Beispiel zum manuellen Testen über den Browser.
export default function handler(req, res) {
  res.setDraftMode({ enable: true })
  res.end('Entwurfsmodus ist aktiviert')
}

Wenn Sie die Entwicklertools Ihres Browsers öffnen und /api/draft besuchen, werden Sie einen Set-Cookie-Antwortheader mit einem Cookie namens __prerender_bypass bemerken.

Sicherer Zugriff von Ihrem Headless-CMS

In der Praxis möchten Sie diese API-Route sicher von Ihrem Headless-CMS aus aufrufen. Die spezifischen Schritte variieren je nach verwendetem Headless-CMS, aber hier sind einige gängige Schritte.

Diese Schritte gehen davon aus, dass das verwendete Headless-CMS die Festlegung von benutzerdefinierten Entwurfs-URLs unterstützt. Falls nicht, können Sie diese Methode trotzdem verwenden, um Ihre Entwurfs-URLs zu sichern, müssen die Entwurfs-URL aber manuell konstruieren und aufrufen.

Erstens sollten Sie einen geheimen Token-String mit einem Token-Generator Ihrer Wahl erstellen. Dieses Geheimnis sollte nur von Ihrer Next.js-App und Ihrem Headless-CMS bekannt sein. Dieses Geheimnis verhindert, dass Personen ohne Zugang zu Ihrem CMS auf Entwurfs-URLs zugreifen.

Zweitens, wenn Ihr Headless-CMS die Festlegung benutzerdefinierter Entwurfs-URLs unterstützt, geben Sie Folgendes als Entwurfs-URL an. Dies setzt voraus, dass Ihre Entwurfs-API-Route sich unter pages/api/draft.ts befindet.

Terminal
https://<ihre-site>/api/draft?secret=<token>&slug=<pfad>
  • <ihre-site> sollte Ihre Bereitstellungsdomäne sein.
  • <token> sollte durch den generierten geheimen Token ersetzt werden.
  • <pfad> sollte der Pfad für die Seite sein, die Sie anzeigen möchten. Wenn Sie /posts/foo anzeigen möchten, verwenden Sie &slug=/posts/foo.

Ihr Headless-CMS erlaubt möglicherweise die Einbindung einer Variable in der Entwurfs-URL, sodass <pfad> dynamisch basierend auf den CMS-Daten gesetzt werden kann: &slug=/posts/{entry.fields.slug}

Schließlich in der Entwurfs-API-Route:

  • Prüfen Sie, ob das Geheimnis übereinstimmt und der slug-Parameter existiert (andernfalls sollte die Anfrage fehlschlagen).
  • Rufen Sie res.setDraftMode auf.
  • Leiten Sie dann den Browser zum angegebenen Pfad um. (Das folgende Beispiel verwendet eine 307-Umleitung).
export default async (req, res) => {
  // Geheimnis und nächste Parameter prüfen
  // Dieses Geheimnis sollte nur dieser API-Route und dem CMS bekannt sein
  if (req.query.secret !== 'MEIN_GEHEIMER_TOKEN' || !req.query.slug) {
    return res.status(401).json({ message: 'Ungültiger Token' })
  }
 
  // Headless-CMS abrufen, um zu prüfen, ob der angegebene `slug` existiert
  // getPostBySlug würde die erforderliche Abruflogik zum Headless-CMS implementieren
  const post = await getPostBySlug(req.query.slug)
 
  // Wenn der Slug nicht existiert, Entwurfsmodus nicht aktivieren
  if (!post) {
    return res.status(401).json({ message: 'Ungültiger Slug' })
  }
 
  // Entwurfsmodus durch Setzen des Cookies aktivieren
  res.setDraftMode({ enable: true })
 
  // Zum Pfad des abgerufenen Beitrags umleiten
  // Wir leiten nicht zu req.query.slug um, da dies zu Umleitungsschwachstellen führen könnte
  res.redirect(post.slug)
}

Bei Erfolg wird der Browser zum gewünschten Pfad mit dem Entwurfsmodus-Cookie umgeleitet.

Schritt 2: getStaticProps aktualisieren

Der nächste Schritt ist die Aktualisierung von getStaticProps, um den Entwurfsmodus zu unterstützen.

Wenn Sie eine Seite mit getStaticProps mit dem gesetzten Cookie anfordern (über res.setDraftMode), wird getStaticProps zur Anforderungszeit (anstatt zur Bauzeit) 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 Entwurfs-API-Route verwendet, daher wird context.draftMode true sein.

Wenn Sie auch getStaticPaths verwenden, wird context.params ebenfalls verfügbar sein.

Entwurfsdaten abrufen

Sie können getStaticProps aktualisieren, um basierend auf context.draftMode unterschiedliche Daten abzurufen.

Beispielsweise könnte Ihr Headless-CMS einen anderen API-Endpunkt für Entwurfsbeiträge haben. In diesem Fall können Sie die API-Endpunkt-URL wie folgt ändern:

export async function getStaticProps(context) {
  const url = context.draftMode
    ? 'https://draft.example.com'
    : 'https://production.example.com'
  const res = await fetch(url)
  // ...
}

Das ist alles! Wenn Sie die Entwurfs-API-Route (mit secret und slug) von Ihrem Headless-CMS oder manuell aufrufen, sollten Sie nun den Entwurfsinhalt sehen können. Und wenn Sie Ihren Entwurf aktualisieren, ohne ihn zu veröffentlichen, sollten Sie den Entwurf anzeigen können.

Setzen Sie dies als Entwurfs-URL in Ihrem Headless-CMS oder rufen Sie es manuell auf, und Sie sollten den Entwurf sehen können.

Terminal
https://<ihre-site>/api/draft?secret=<token>&slug=<pfad>

Weitere Details

Standardmäßig endet die Entwurfsmodus-Sitzung, wenn der Browser geschlossen wird.

Um den Entwurfsmodus-Cookie manuell zu löschen, erstellen Sie eine API-Route, die setDraftMode({ enable: false }) aufruft:

pages/api/disable-draft.ts
export default function handler(req, res) {
  res.setDraftMode({ enable: false })
}

Senden Sie dann eine Anfrage an /api/disable-draft, um die API-Route aufzurufen. Wenn Sie diese Route mit next/link aufrufen, müssen Sie prefetch={false} übergeben, um versehentliches Löschen des Cookies beim Prefetching zu verhindern.

Funktioniert mit getServerSideProps

Der Entwurfsmodus funktioniert mit getServerSideProps und ist als draftMode-Schlüssel im context-Objekt verfügbar.

Hinweis: Sie sollten den Cache-Control-Header beim Verwenden des Entwurfsmodus nicht setzen, da er nicht umgangen werden kann. Stattdessen empfehlen wir die Verwendung von ISR.

Funktioniert mit API-Routen

API-Routen haben Zugriff auf draftMode im Anfrageobjekt. Beispiel:

export default function myApiRoute(req, res) {
  if (req.draftMode) {
    // Entwurfsdaten abrufen
  }
}

Eindeutig pro next build

Bei jedem Ausführen von next build wird ein neuer Bypass-Cookie-Wert generiert.

Dies stellt sicher, dass der Bypass-Cookie nicht erraten werden kann.

Hinweis: Um den Entwurfsmodus lokal über HTTP zu testen, muss Ihr Browser Drittanbieter-Cookies und lokalen Speicherzugriff erlauben.