跳到内容

草稿模式

草稿模式 允许你在你的 Next.js 应用程序中预览来自你的 Headless 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:从你的 Headless CMS 访问路由处理器

这些步骤假设你使用的 Headless CMS 支持设置自定义草稿 URL。如果不支持,你仍然可以使用此方法来保护你的草稿 URL,但你需要手动构建和访问草稿 URL。具体步骤将因你使用的 Headless CMS 而异。

要从你的 Headless CMS 安全地访问路由处理器

  1. 使用你选择的令牌生成器创建一个 密钥令牌字符串。此密钥将仅为你的 Next.js 应用程序和你的 Headless CMS 所知。
  2. 如果你的 Headless 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

你的 Headless CMS 可能允许你在草稿 URL 中包含一个变量,以便可以根据 CMS 的数据动态设置 <path>,如下所示:&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>
  )
}

如果你从你的 Headless CMS 或手动使用 URL 访问草稿路由处理器(带有 secretslug),你现在应该能够看到草稿内容。并且,如果你在不发布的情况下更新你的草稿,你应该能够查看草稿。

下一步

有关如何使用草稿模式的更多信息,请参阅 API 参考。