草稿模式
草稿模式 允许你在你的 Next.js 应用程序中预览来自你的 Headless CMS 的草稿内容。这对于在构建时生成的静态页面非常有用,因为它允许你切换到 动态渲染 并查看草稿更改,而无需重新构建你的整个站点。
此页面将引导你完成如何启用和使用草稿模式。
步骤 1:创建一个路由处理器
创建一个 路由处理器。它可以有任何名称,例如,app/api/draft/route.ts
。
export async function GET(request: Request) {
return new Response('')
}
然后,导入 draftMode
函数并调用 enable()
方法。
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 安全地访问路由处理器
- 使用你选择的令牌生成器创建一个 密钥令牌字符串。此密钥将仅为你的 Next.js 应用程序和你的 Headless CMS 所知。
- 如果你的 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}
- 在你的路由处理器中,检查密钥是否匹配以及
slug
参数是否存在(如果不存在,则请求应失败),调用draftMode.enable()
以设置 cookie。然后,将浏览器重定向到slug
指定的路径
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
。
// 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 访问草稿路由处理器(带有 secret
和 slug
),你现在应该能够看到草稿内容。并且,如果你在不发布的情况下更新你的草稿,你应该能够查看草稿。
这有帮助吗?