跳到內容
App Router指南草稿模式

如何在 Next.js 中使用草稿模式預覽內容

草稿模式允許你在 Next.js 應用程式中預覽來自無頭 CMS 的草稿內容。這對於在構建時生成的靜態頁面很有用,因為它允許你切換到動態渲染並檢視草稿更改,而無需重新構建整個站點。

本頁面介紹瞭如何啟用和使用草稿模式。

步驟 1:建立路由處理程式

建立一個路由處理程式。它可以是任何名稱,例如 app/api/draft/route.ts

app/api/draft/route.ts
export async function GET(request: Request) {
  return new Response('')
}

然後,匯入 draftMode 函式並呼叫 enable() 方法。

app/api/draft/route.ts
import { draftMode } from 'next/headers'
 
export async function GET(request: Request) {
  const draft = await draftMode()
  draft.enable()
  return new Response('Draft mode is enabled')
}

這將設定一個 cookie 以啟用草稿模式。後續包含此 cookie 的請求將觸發草稿模式並改變靜態生成頁面的行為。

你可以透過訪問 /api/draft 並檢視瀏覽器開發者工具手動測試。請注意 Set-Cookie 響應頭中名為 __prerender_bypass 的 cookie。

步驟 2:從無頭 CMS 訪問路由處理程式

這些步驟假設你使用的無頭 CMS 支援設定自定義草稿 URL。如果不支援,你仍然可以使用此方法保護你的草稿 URL,但你需要手動構造和訪問草稿 URL。具體步驟將因你使用的無頭 CMS 而異。

要從無頭 CMS 安全地訪問路由處理程式

  1. 使用你選擇的令牌生成器建立秘密令牌字串。此秘密將僅由你的 Next.js 應用和你的無頭 CMS 知道。
  2. 如果你的無頭 CMS 支援設定自定義草稿 URL,請指定草稿 URL(這假設你的路由處理程式位於 app/api/draft/route.ts)。例如
終端
https://<your-site>/api/draft?secret=<token>&slug=<path>
  • <your-site> 應該是您的部署域名。
  • <token> 應該替換為您生成的秘密令牌。
  • <path> 應該是你想要檢視的頁面的路徑。如果你想檢視 /posts/one,那麼你應該使用 &slug=/posts/one

你的無頭 CMS 可能允許你在草稿 URL 中包含一個變數,以便 <path> 可以根據 CMS 的資料動態設定,例如:&slug=/posts/{entry.fields.slug}

  1. 在你的路由處理程式中,檢查秘密是否匹配以及 slug 引數是否存在(如果不存在,請求應失敗),呼叫 draftMode.enable() 以設定 cookie。然後,將瀏覽器重定向到 slug 指定的路徑
app/api/draft/route.ts
import { draftMode } from 'next/headers'
import { redirect } from 'next/navigation'
 
export async function GET(request: Request) {
  // Parse query string parameters
  const { searchParams } = new URL(request.url)
  const secret = searchParams.get('secret')
  const slug = searchParams.get('slug')
 
  // Check the secret and next parameters
  // This secret should only be known to this Route Handler and the CMS
  if (secret !== 'MY_SECRET_TOKEN' || !slug) {
    return new Response('Invalid token', { status: 401 })
  }
 
  // Fetch the headless CMS to check if the provided `slug` exists
  // getPostBySlug would implement the required fetching logic to the headless CMS
  const post = await getPostBySlug(slug)
 
  // If the slug doesn't exist prevent draft mode from being enabled
  if (!post) {
    return new Response('Invalid slug', { status: 401 })
  }
 
  // Enable Draft Mode by setting the cookie
  const draft = await draftMode()
  draft.enable()
 
  // Redirect to the path from the fetched post
  // We don't redirect to searchParams.slug as that might lead to open redirect vulnerabilities
  redirect(post.slug)
}

如果成功,瀏覽器將重定向到你想要檢視的路徑,並帶有草稿模式 cookie。

步驟 3:預覽草稿內容

下一步是更新你的頁面以檢查 draftMode().isEnabled 的值。

如果你請求設定了 cookie 的頁面,那麼資料將在請求時(而不是在構建時)獲取。

此外,isEnabled 的值將為 true

app/page.tsx
// page that fetches data
import { draftMode } from 'next/headers'
 
async function getData() {
  const { isEnabled } = await draftMode()
 
  const url = isEnabled
    ? 'https://draft.example.com'
    : 'https://production.example.com'
 
  const res = await fetch(url)
 
  return res.json()
}
 
export default async function Page() {
  const { title, desc } = await getData()
 
  return (
    <main>
      <h1>{title}</h1>
      <p>{desc}</p>
    </main>
  )
}

如果你從無頭 CMS 或手動使用 URL 訪問草稿路由處理程式(帶有 secretslug),現在應該能夠看到草稿內容。而且,如果你在未釋出的情況下更新草稿,你應該能夠檢視草稿。

下一步

有關如何使用草稿模式的更多資訊,請參閱 API 參考。