Vercel 内容链接(Vercel Content Link)

Vercel 内容链接可以让你的编辑人员从前端渲染的内容直接跳转到 Payload 中控制这些内容的字段。这不需要对你的前端代码做任何修改,对 Payload 配置的改动也非常少。

版本

Vercel 内容链接是企业版专属功能,仅适用于部署在 Vercel 上的项目。如果您已经是企业客户, 联系我们的销售团队获取集成帮助。

工作原理

为了实现 Vercel 内容链接功能,Payload 会在 API 响应中嵌入内容源映射(Content Source Maps)。这些内容源映射是经过编码的、不可见的 JSON 值,包含指向 CMS 中生成该内容的字段的链接。当这些内容在页面上渲染时,Vercel 会检测并解码这些值,从而显示内容链接界面。

关于编码和解码算法的完整细节,请查看 @vercel/stega

快速开始

将 Payload 与 Vercel Content Link 集成非常简单。首先,在你的项目中安装 @payloadcms/plugin-csm 插件。该插件需要 API 密钥才能安装,如果你还没有密钥,请联系我们的销售团队

npm i @payloadcms/plugin-csm

然后在 Payload Config 的 plugins 数组中调用该插件,并启用需要内容源映射(Content Source Maps)的集合。

import { buildConfig } from "payload/config"
import contentSourceMaps from "@payloadcms/plugin-csm"

const config = buildConfig({
  collections: [
    {
      slug: "pages",
      fields: [
        {
          name: 'slug',
          type: 'text',
        },
        {
          name: 'title,'
          type: 'text',
        },
      ],
    },
  ],
  plugins: [
    contentSourceMaps({
      collections: ["pages"],
    }),
  ],
})

export default config

启用内容源映射

现在,在你的 Next.js 应用中,你需要在 API 请求中添加 encodeSourceMaps 查询参数。这将告诉 Payload 在 API 响应中包含内容源映射。

注意: 出于性能考虑,此功能应仅在草稿模式或预览部署时启用。

REST API

如果你使用 REST API,请包含 ?encodeSourceMaps=true 搜索参数。

if (isDraftMode || process.env.VERCEL_ENV === 'preview') {
  const res = await fetch(
    `${process.env.NEXT_PUBLIC_PAYLOAD_CMS_URL}/api/pages?encodeSourceMaps=true&where[slug][equals]=${slug}`,
  )
}

本地 API

如果你正在使用 Local API,需要通过 context 属性包含 encodeSourceMaps

if (isDraftMode || process.env.VERCEL_ENV === 'preview') {
  const res = await payload.find({
    collection: 'pages',
    where: {
      slug: {
        equals: slug,
      },
    },
    context: {
      encodeSourceMaps: true,
    },
  })
}

这样就完成了!你现在可以进入编辑模式并开始可视化编辑你的内容了。

编辑模式

要在你的网站上看到 Content Link,首先需要访问 Vercel 上的任何预览部署并使用 Vercel 工具栏登录。当页面检测到 Content Source Maps 时,工具栏中会出现一个铅笔图标。点击该图标将启用编辑模式,页面上所有可编辑字段会以蓝色高亮显示。

Versions

故障排除

日期字段

该插件默认不会编码 date 字段,但对于某些情况(如使用负 CSS letter-spacing 的文本),可能需要将编码数据从渲染文本中分离出来。这样你就可以安全地使用清理后的数据。

import { vercelStegaSplit } from '@vercel/stega'
const { cleaned, encoded } = vercelStegaSplit(text)

区块和数组字段

所有 blocksarray 字段根据定义都不包含纯文本字符串进行编码。因此,它们会自动获得一个额外的 _encodedSourceMap 属性,你可以使用该属性在网站的整个 区块 上启用 Content Link。

然后,你可以通过向区块的任何顶层元素添加 data-vercel-edit-target HTML 属性来指定编辑容器。

<div data-vercel-edit-target>
  <span style={{ display: "none" }}>{_encodedSourceMap}</span>
  {children}
</div>