如何在 Next.js 中使用草稿模式预览内容
在页面文档和数据获取文档中,我们讨论了如何使用 getStaticProps
和 getStaticPaths
在构建时预渲染页面(静态生成)。
当页面从无头 CMS 获取数据时,静态生成非常有用。但如果您正在无头 CMS 上撰写草稿并希望立即在页面上查看,这种方式就不理想了。此时您会希望 Next.js 在请求时而非构建时渲染这些页面,并获取草稿内容而非已发布内容。您需要 Next.js 仅在此特定情况下绕过静态生成。
Next.js 的草稿模式 (Draft Mode) 功能正是为此而生。以下是使用指南。
第一步:创建并访问 API 路由
如果您不熟悉 Next.js API 路由,请先查阅 API 路由文档。
首先创建 API 路由,可任意命名(例如 pages/api/draft.ts
)。
在此 API 路由中,需在响应对象上调用 setDraftMode
。
这将设置一个Cookie来启用草稿模式。后续携带此 Cookie 的请求将触发草稿模式,从而改变静态生成页面的行为(下文详述)。
您可以通过手动创建如下 API 路由并从浏览器访问来测试:
如果在浏览器开发者工具中访问 /api/draft
,会注意到响应头中有 Set-Cookie
字段,其值为名为 __prerender_bypass
的 Cookie。
从无头 CMS 安全访问
实际应用中,您需要从无头 CMS安全地调用此 API 路由。具体步骤因 CMS 而异,但以下是通用方案:
此方案假设您的无头 CMS 支持设置自定义草稿 URL。若不支持,您仍可用此方法保护草稿 URL,但需手动构建和访问。
首先,使用任意令牌生成器创建密钥字符串。该密钥仅由 Next.js 应用和无头 CMS 知晓,可防止无 CMS 访问权限者获取草稿 URL。
其次,若 CMS 支持自定义草稿 URL,请将以下内容设为草稿 URL(假设草稿 API 路由位于 pages/api/draft.ts
):
<your-site>
替换为部署域名<token>
替换为生成的密钥<path>
替换为目标页面路径(如欲查看/posts/foo
,则使用&slug=/posts/foo
)
某些 CMS 允许在草稿 URL 中包含变量,从而动态设置 <path>
,例如:&slug=/posts/{entry.fields.slug}
最后,在草稿 API 路由中:
- 检查密钥是否匹配及
slug
参数是否存在(否则请求应失败) - 调用
res.setDraftMode
- 重定向浏览器到
slug
指定路径(下例使用 307 重定向)
成功后,浏览器将携带草稿模式 Cookie 重定向到目标路径。
第二步:更新 getStaticProps
接下来需更新 getStaticProps
以支持草稿模式。
若请求的页面具有 getStaticProps
且已设置 Cookie(通过 res.setDraftMode
),则 getStaticProps
将在请求时被调用(而非构建时)。
此外,其调用时将接收 context
对象,其中 context.draftMode
为 true
。
由于我们在草稿 API 路由中使用了 res.setDraftMode
,故 context.draftMode
将为 true
。
若同时使用 getStaticPaths
,则 context.params
也可用。
获取草稿数据
可根据 context.draftMode
修改 getStaticProps
以获取不同数据。
例如,无头 CMS 可能有专用的草稿文章 API 端点。此时可如下修改端点 URL:
完成!现在从无头 CMS 或手动访问草稿 API 路由(携带 secret
和 slug
)即可查看草稿内容。当您更新草稿但未发布时,也能立即查看。
将此 URL 设为无头 CMS 的草稿 URL 或手动访问:
更多细节
清除草稿模式 Cookie
默认情况下,草稿模式会话在浏览器关闭时结束。
要手动清除 Cookie,可创建调用 setDraftMode({ enable: false })
的 API 路由:
然后向 /api/disable-draft
发送请求。若使用 next/link
调用此路由,必须传递 prefetch={false}
以防预取时意外删除 Cookie。
与 getServerSideProps
协作
草稿模式可与 getServerSideProps
协同工作,在上下文对象中以 draftMode
键存在。
须知:使用草稿模式时不应设置
Cache-Control
标头,因其无法被绕过。建议改用 ISR。
与 API 路由协作
API 路由可通过请求对象的 draftMode
访问该状态。例如:
每次 next build
生成唯一值
每次运行 next build
都会生成新的绕过 Cookie 值。
这确保了绕过 Cookie 无法被猜测。
须知:要通过 HTTP 在本地测试草稿模式,浏览器需允许第三方 Cookie 和本地存储访问。