如何在 Next.js 网站中添加结构化数据(JSON-LD)并验证

如何在 Next.js 网站中添加结构化数据(JSON-LD)并验证

💡 原文英文,约4600词,阅读约需17分钟。
📝

内容提要

本文介绍在 Next.js App Router 中添加 JSON-LD 结构化数据的方法:创建可复用的 JsonLd 组件并转义 `<` 防止 XSS;首页添加 Organization 与 WebSite 数据,动态路由基于页面同源数据生成 Article 和面包屑;通过检查 HTML 输出、在线验证工具及构建后自动校验脚本,确保数据有效且与可见内容一致。

🔎

延伸解读

结构化数据不是排名捷径

文章明确引用Google的John Mueller在2025年的说法:结构化数据不会让网站排名更好。它的作用是帮助搜索引擎理解页面内容,并让页面有资格获得富媒体搜索结果,但“有资格”不等于“一定展示”。Google的指南也强调,即使标记正确,也不保证富媒体结果会出现。因此,添加JSON-LD时应把它当作内容描述工具,而非SEO技巧。

转义小于号是安全底线

JSON.stringify生成的字符串虽然符合JSON语法,但直接嵌入HTML的script标签时,若数据中包含</script>,浏览器会提前结束标签,导致XSS攻击或JSON解析失败。文章通过jsdom测试证明,未转义时alert会执行,JSON.parse报错。将<替换为\u003c后,浏览器找不到</script>,JSON解析器仍能还原原字符。任何来自CMS或用户输入的值都必须转义。

用构建后脚本防止静默回归

结构化数据常在后期悄悄失效:CMS字段改名、重构删除属性、标题更新但JSON-LD未同步。文章提供的check-jsonld.mjs脚本在每次构建后抓取页面,检查JSON有效性、@context、必需属性以及BlogPosting标题是否与页面h1一致。它不依赖外部服务,退出码非零可让CI失败,从而在部署前拦截问题。这比手动使用在线验证工具更可持续。

JSON-LD会随RSC负载重复传输

文章指出,Next.js会将渲染后的React树作为React Server Components负载再发送一次,因此JSON-LD字符串会在HTML中传输两遍。这意味着结构化数据会占用额外带宽。作者建议只保留必要的属性,不要把整篇文章正文塞进JSON-LD。这一细节提醒开发者,结构化数据虽小,但在大型站点上重复传输可能累积成可观的体积。

❓

Q&A

在 Next.js 中,为什么不能直接用 JSON.stringify 来输出 JSON-LD?

因为 JSON.stringify 生成的字符串可能包含 `</script>` 等序列,浏览器会在第一个 `</script>` 处提前结束 script 标签,导致 JSON 被截断,甚至执行注入的脚本,造成 XSS 攻击。必须将 `<` 转义为 `\u003c`,这样浏览器找不到 `</script>`,而 JSON 解析器仍能正确还原字符。

为什么在 Next.js 中推荐用普通的 <script> 标签而不是 next/script 来渲染 JSON-LD?

next/script 是为加载和执行 JavaScript 优化的,默认的 afterInteractive 策略会将内容在客户端注入 HTML。这样构建后的 HTML 中不会有 application/ld+json 标签,只有 JavaScript 能读取到数据。而普通 <script> 标签会将数据直接放在服务器发送的 HTML 中,所有只读取 HTML 的工具都能看到。

在 Next.js 动态路由中,如何确保文章的结构化数据与页面可见内容一致?

应该从页面渲染所用的同一份数据(如 getPost() 返回的 post 对象)来构建 JSON-LD。例如 headline 取自 post.title,author 取自 post.author,日期取自 post.publishedAt 等。这样当内容更新时,结构化数据会自动同步,避免硬编码导致的不一致。

如何验证 Next.js 网站中的 JSON-LD 是否正确输出到了 HTML 中?

构建并启动应用后,用 curl 获取页面并 grep 提取 JSON-LD 块,例如:`curl -s http://localhost:3000/blog/nextjs-caching | grep -o '<script type="application/ld+json">[^<]*</script>'`。如果数据只在客户端注入,grep 将找不到任何内容。也可以使用浏览器查看源代码,但不要用开发者工具的 Elements 面板,因为它显示的是 JavaScript 执行后的 DOM。

有哪些在线工具可以验证结构化数据?它们有什么区别?

Rich Results Test 是 Google 的工具,显示页面符合哪些富媒体搜索结果类型以及错误或建议,最好用 URL 测试。Schema Markup Validator 检查标记是否符合 Schema.org 词汇表本身,不检查 Google 的富媒体结果类型。开发时用 Rich Results Test,部署后用 Google Search Console 的富媒体结果报告。

如何自动验证 JSON-LD 以确保每次构建后结构化数据都有效?

可以编写一个 Node 脚本,在构建后运行。脚本从运行中的服务器获取页面,检查每个 JSON-LD 块是否为有效 JSON、@context 是否为 https://schema.org、是否包含承诺的属性(如 Organization 的 name、url、logo),以及 BlogPosting 的 headline 是否与页面的 <h1> 匹配。脚本在发现错误时以非零退出码结束,可集成到 CI 中。

结构化数据能保证获得 Google 富媒体搜索结果吗?

不能。有效的 JSON-LD 只是让页面有资格获得富媒体结果,但 Google 不保证一定会显示。每个富媒体结果类型有自己必需的属性,Google 自行决定是否展示,且标记必须描述页面上可见的内容。此外,结构化数据不是排名提升因素。

🏷️

标签

➡️

继续阅读