毫无疑问 -Jamstack将继续存在。自从Matt Biilmann在 2016 年将概念带入主流以来,基于此架构的整个生态系统如雨后春笋般涌现(包括我们自己的 Speed 层 Enterspeed,但稍后会详细介绍)。

开发人员喜欢 Jamstack 架构可以为站点本身和项目工作流程带来的好处。我们不会深入探讨本文中的许多好处,因为关于这个主题的书籍可能是(和)。

然而,一个网站很少由开发人员单独运营,而是由广泛的人运营,例如内容创建者,如文案、营销人员、支持者等。在开发新网站时,必须考虑所有这些人。

[图像描述](https://res.cloudinary.com/practicaldev/image/fetch/s--nlHpxeK_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/ev8h6etuz2m75zzpu8ya.jpg)

大多数内容创建者过去都使用过某种 CMS,例如 WordPress,并且已经习惯了编辑器的体验。

内容创建者经常使用的关键功能之一是在发布之前预览其内容的选项。

这在使用 SSG(静态站点生成)时可能有点棘手,因为我们希望在请求时而不是构建时呈现这些页面。

即使我们的开发人员认为我们的 IDE 是我们的第二故乡,大多数内容创建者并不热衷于启动项目的本地实例来预览他们的内容(我知道,对吗?)。

幸运的是,Next.js背后的优秀团队为这个问题想出了一个绝妙的解决方案 -Preview mode。

设置预览模式使您能够绕过 SSG 并在请求时呈现页面。那么它是如何工作的以及我们如何启用它呢?让我们研究一下。

在 Next.js 中设置预览模式

👉 注意: 本文基于Next.js 的精彩文档,因此会出现类似的措辞和代码示例。

在Next.js repo中,您将找到大量示例,说明如何使用 Next.js 的预览模式设置无头 CMS。在本教程中,我们将基于我们自己的解决方案 Enterspeed 的示例。

什么是Enterspeed?

Enterspeed 是一个 Speed 层,可让您将所有服务连接并组合到单个 API 端点中。我们的低编辑器可以轻松转换您的数据,以获得您所需要的——所有这些都存储在我们超快的边缘网络中。

这使其成为加速遗留系统的理想选择,例如Umbraco 解决方案.

好吧,足够的自我推销 - 这只是为您提供以下示例的背景信息。

1\。创建预览 API 路由

Next.js 提供了构建 API 的解决方案。这是通过在 pages 文件夹 (pages/api) 中创建一个名为 api 的文件夹来完成的。此文件夹中的任何文件都将被视为 API 端点而不是页面。

在 pages/api 文件夹中创建一个名为 preview.js 的文件(如果您使用的是 TypeScript,则为 .ts)。

在响应对象(res)上,我们会调用setPreviewData,它会通过设置一些cookies来开启预览模式。

[图像描述](https://res.cloudinary.com/practicaldev/image/fetch/s--ejv9njOI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/jkac45ubefw3g5dyyu4p.png)

访问 API 路由后,您可以打开浏览器的开发者工具,查看 __prerender_bypass__next_preview_data cookie 是否已设置。

**💡提示:**您可以指定预览模式的持续时间。 setPreviewData 采用可选的第二个参数(选项对象)。在对象内部,将键设置为 maxAge 以及预览会话应持续多长时间(以秒为单位)的值。

[图像描述](https://res.cloudinary.com/practicaldev/image/fetch/s--SaoMpgpq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/25ajjhvut46lq4pu4u9j.png)

所有具有这些 cookie 的 Next.js 请求现在都将被视为预览模式,这将修改静态生成的页面的行为方式。

由于您不希望任何人访问您的预览内容,一个好主意是为您的预览 URL 创建一个秘密令牌字符串。您可以使用众多令牌生成器之一,例如RandomKeygen.com来生成您的秘密令牌。

💡提示: 将您的密码存储在环境变量中,并让您的团队将预览 URL(包括密码令牌)保存在 1Password 等密码管理器中。

[图像描述](https://res.cloudinary.com/practicaldev/image/fetch/s--ysByY-Ee--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/uploads/articles/56e8vxz4kuq3iag7tabv.png)

👉 注意: 如果您的无头 CMS 支持设置自定义预览 URL,您可以实现重定向到获取的帖子的获取逻辑。在此示例中,我们只是重定向到 root。

接下来,让我们通过清除预览模式 cookie 来实现再次禁用预览模式的方法。

在 api 文件夹 (pages/api) 中创建一个名为 clear-preview.js 的新文件。这里你需要在响应对象上调用clearPreviewData

[图像描述](https://res.cloudinary.com/practicaldev/image/fetch/s--7bOi1v1z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/q42895q2423g7sft2jw7.png)

访问此 API 路由后,您可以打开浏览器的开发人员工具,查看 __prerender_bypass__next_preview_data cookie 已被删除。

💡 提示: 为了更简洁的 URL 结构,您可以在 api 文件夹中创建一个名为 preview 的文件夹,并将 preview.js 重命名为 index.js。然后你可以简单地将 clear-preview.js 命名为 clear.js,它可以通过 /api/preview/clear 获得。

2\。更新 getStaticProps

getStaticProps 函数在 SSG 中用于在构建时使用 getStaticProps 返回的道具预渲染页面。

但是,启用预览模式后,getStaticProps 将在请求时调用,而不是在构建时调用。

它还将有一个 context 对象,其中 context.preview 将为 true,这是我们将使用的对象。为了使代码更易于阅读,我们可以像这样破坏 context 对象。

[图像描述](https://res.cloudinary.com/practicaldev/image/fetch/s--e5f31FB9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/bfw03w5dhxj4drealb1u.png)

接下来,我们将根据 preview 是否为真来获取不同的数据。如何完成此操作可能因您的 CMS 而异。

在我们的例子中,使用 Enterspeed,我们有一个 API 调用函数,它将预览上下文作为参数。根据其值(真/假),它将从我们的预览数据源或生产数据源中获取内容。

👉 注意: Enterspeed 将预览数据存储在单独的数据源中,您的解决方案可能并非如此。

[图像描述](https://res.cloudinary.com/practicaldev/image/fetch/s--Lys_-h0N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/uploads/articles/1yycbmqmf84pni9xqli2.png)

在我们的 getStaticProps 函数中,我们将 Preview 上下文传递给我们的 getByUrl 函数,该函数将它传递给我们的 API 调用函数。

[图像描述](https://res.cloudinary.com/practicaldev/image/fetch/s--dRNI16HA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/y7de0947j4tlgk0rr2it.png)

额外提示:实现预览栏

为了帮助我们的内容创建者了解是否启用了预览模式,我们在项目中实现了“预览栏”。

[图像描述](https://res.cloudinary.com/practicaldev/image/fetch/s--0weZs6h_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/t5el3asmmm00o8r3cds4.png)

有多种方法可以做到这一点,每种方法都有自己的缺点。

由于我们希望预览栏在我们的整个站点中可见(以确保内容创建者知道他们启用了预览模式),我们决定在启用预览模式后设置一个会话 cookie。

我们本可以使用 getInitialProps 来检查 _app.js 中的 Preview 上下文,不幸的是,这禁用了我们不感兴趣的自动静态优化。

由于我们无法通过 API 路由设置会话 cookie,因此我们通过了查询 /?previewu003dtrue&secretu003d${process.env.ENTERSPEED_PREVIEW_SECRET}

在 api/preview.js 中的 res.redirect 上。这个秘密并不是绝对必要的,只是为了帮助确保预览参数是通过 API 路由设置的。

接下来,我们创建了两个辅助函数,其中一个检查 previewMode 会话 cookie 是否设置为启用,另一个用于管理 previewMode 会话 cookie。它通过使用 next/router 来检查 preview 参数是否为 true 以及 secret 参数是否与我们的 secret 匹配。

如果是这样,我们将会话 cookie previewMode 设置为启用。如果 preview 参数等于“clear”,我们就再次删除 cookie。

在这两个函数中,我们还检查是否可以访问窗口对象,因此我们可以设置 cookie。

[图像描述](https://res.cloudinary.com/practicaldev/image/fetch/s--WYl9jOKm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/xeh004xr628xod84apnw.png)

在我们的 _app.js 中,我们然后调用我们的 managePreviewSessionStorage() 函数。我们还检查 checkPreviewSessionStorage 是否返回 true,如果是,我们渲染PreviewBar 组件。

就是这样。现在开发者和内容创作者都可以开心了🙌

👋 我希望您喜欢这篇文章,如果您有兴趣了解有关 Enterspeed 的更多信息,您可以通过enterspeed.com查看我们

Logo

React社区为您提供最前沿的新闻资讯和知识内容

更多推荐