最快修法:拿一个失败 URL 在 Rich Results Test 里打开,逐字读报错原文,再 view-source 看页面里的 <script type="application/ld+json"> block。坏掉的几乎总是这四种之一——重命名了 frontmatter 字段但 JSON-LD 还在用旧名、框架的序列化器改了日期或数组格式、新加的 layout wrapper 在脚本进 <head> 前把它丢了,或者条件渲染分支现在漏掉了一批页面。不用重写整个 schema,找到那一个回退的字段补上就行。
这种情况通常在你重构文章 layout、升级 Astro / Next.js / Hugo 或重命名 content collection 字段一周后冒出来:Search Console 发邮件「Structured data issues detected」,Enhancements 报告(Search Console → 左侧导航 → Enhancements,按类型分列:Articles、Breadcrumbs、Merchant listings 等)某个类型一片红。
2026 年 6 月注意:FAQ rich results 已经下线了。 Google 在 2026 年 5 月 7 日停止在搜索里展示 FAQ rich result,6 月移除了 FAQ 报告以及 Rich Results Test 里的 FAQ 支持,8 月会从 Search Console API 里去掉 FAQ 数据(见 Google 的 FAQ changelog)。HowTo rich results 更早,桌面端在 2023 年 9 月就移除了。
FAQPage/HowTo标记作为 Schema.org 类型仍然有效,留着也不会报错——只是不再换来 SERP 富媒体展示,所以别再去追一个已经不存在的「坏掉的 FAQPage」rich result。
15 秒判断你是哪种情况
抽样失败 URL 用 Rich Results Test 打开,逐字读错误原文(别按你的理解概括)。错误措辞直接映射到具体原因:
| Rich Results Test 报错 | 最可能的原因 |
|---|---|
Missing field "datePublished" / "author" / "image" | 重命名了 frontmatter 字段;JSON-LD 还引用旧名,结果是 undefined |
Invalid object type for field "X" | 框架升级改了值的序列化方式(Date → 字符串、数组 → 对象) |
Parsing error: ... 或 “No items detected” / “No structured data detected” | JSON-LD block 已经不在渲染出的 HTML 里——被 wrapper、hydration 或条件分支吞掉了 |
Either "image" or "thumbnailUrl" should be specified | 图片 helper 现在返回相对路径或 null |
BreadcrumbList: itemListElement must contain at least 2 items | 面包屑生成器对部分路由返回 0 或 1 项 |
Article: A value for the headline field is required | 标题字段被重命名,或现在解析成了空字符串 |
如果你只看到针对 FAQPage 的报错,直接忽略:截至 2026 年 6 月,这个类型已经不产生 rich result,Rich Results Test 也不再对它报错了。
常见原因(按命中率排序)
1. 重命名了 frontmatter 字段,JSON-LD 还在用旧名
你把 content collection schema 里 pubDate 改成了 publishedAt。JSON-LD 模板还在读 frontmatter.pubDate,现在它是 undefined。输出长这样:
{
"@context": "https://schema.org",
"@type": "Article",
"datePublished": null
}
Google 不接受必填字段为 null / 缺失。
怎么判断:view-source 页面找 <script type="application/ld+json">,看是否有 null、缺 key 或者本应有值但是空字符串的字段。
修复:grep 代码库里 JSON-LD 生成器引用的每个字段名,逐个对照当前 frontmatter schema。简单守卫:
const datePublished = frontmatter.publishedAt ?? frontmatter.pubDate;
if (!datePublished) throw new Error(`Missing publishedAt for ${slug}`);
让构建直接失败比两周后在 Search Console 里看到错更早。
2. 框架升级改了序列化方式
Astro / Next.js minor 升级后常见坑:Date 对象原来 JSON.stringify 出 ISO 字符串,现在序列化成 {} 或本地化字符串;数组里的对象被拍扁。
怎么判断:diff 上一个能用的 commit 和当前的 view-source。看是否有字段原来是 "2026-05-19T00:00:00.000Z" 现在变成了 "5/19/2026" 或 {}。
修复:所有日期显式转 ISO 8601:
const datePublished = new Date(frontmatter.publishedAt).toISOString();
数组也显式序列化,别依赖 JSON.stringify 默认行为。
3. 新加的 layout wrapper 吞掉了 JSON-LD
你给文章包了个 <MarketingShell> 或 <ArticleFrame>。如果这个组件有自己的 <head> slot 或者过滤了 children,你的 <script type="application/ld+json"> 就到不了 document head。
怎么判断:Rich Results Test 报「No structured data detected」。view-source 整个页面:JSON-LD <script> 完全不见。模板源代码里有,但渲染时没活下来。
修复:Astro 用 <Fragment slot="head"> 或直接在 layout 的 <head> 里渲染脚本;Next.js 用 <Head> 或 App Router 的 generateMetadata / Script strategy="beforeInteractive";Hugo 确认 partial 在 head.html 里 include。
4. 条件渲染分支漏了一批页面
模板里有 {frontmatter.draft ? null : <JsonLd />} 或 {frontmatter.type === 'guide' && <JsonLd />}。重构后条件覆盖范围变了——比如老文章 type 是 undefined,全被排除。
怎么判断:Search Console Enhancements 显示「valid items」精确掉了 N 条。筛 URL 会发现它们共享一个 frontmatter 特征(老日期、缺字段、特定 category)。
修复:对 Google 仍然会渲染的类型,让 JSON-LD 生成器无条件输出;只在某类型对这个页面确实不适用时才不输出。Article / BreadcrumbList / WebSite 一律无条件输出。
5. BreadcrumbList itemListElement 数量不对
路由重构后,面包屑生成器对某些路由只返回 1 项(Home)或返回重复项(Home > Home > Article)。Google 要求至少 2 项且 position 不重复。
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "Home", "item": "https://yourdomain.com/" },
{ "@type": "ListItem", "position": 2, "name": "Troubleshooting", "item": "https://yourdomain.com/troubleshooting/" },
{ "@type": "ListItem", "position": 3, "name": "文章标题" }
]
}
注意:最后一项不能有 item URL——它代表当前页。
可直接复制的 Article + Breadcrumb 模板
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "标题,控制在 110 字符以内",
"description": "一句话摘要",
"image": "https://yourdomain.com/og/article.png",
"datePublished": "2026-05-19T00:00:00.000Z",
"dateModified": "2026-05-22T00:00:00.000Z",
"author": {
"@type": "Person",
"name": "作者名",
"url": "https://yourdomain.com/about/"
},
"publisher": {
"@type": "Organization",
"name": "站点名",
"logo": {
"@type": "ImageObject",
"url": "https://yourdomain.com/logo.png"
}
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://yourdomain.com/articles/article-slug/"
}
}
最短修复路径
按命中率排序:
- 逐字读 Rich Results Test 错误原文 —— 它直接告诉你坏的是哪个字段
- view-source 找 JSON-LD block,搜
null、缺 key、旧字段名 - diff 上一个能用的 commit —— 多数 regression 来自某一处具体改动
- 加构建期 JSON-LD 校验:必填字段缺失直接 fail build —— 防下一次回归
- 抽样页在 Search Console URL Inspection 重新请求索引;Enhancements 报告 1-3 周自然清理
预防建议
- 每次构建用
schema-dts做类型检查校验原始 JSON-LD 语法(字段被重命名或类型写错会变成 TypeScript 编译错误,而不是运行时才暴雷)。临时想对照完整 Schema.org 词表查语法,把标记粘进 Schema Markup Validator——那是通用语法工具,而 Rich Results Test 只覆盖仍能换来 Google rich result 的类型。 - JSON-LD 模板不直接引用 frontmatter 字段——走一个强类型 helper,必填字段缺失就抛,让构建直接失败,而不是两周后才被 Search Console 抓到。
- 框架升级后,合并前对每种内容类型至少一个 URL 跑一次 Rich Results Test。还没部署的分支用 Code Snippet 模式,或者对着 preview 部署用 URL 模式。
- 留一个「schema canary」路由——一个会输出你站点所有 schema 类型的 fixture 页面,CI 里固定校验它,这样一旦某次改 layout 把
<script>block 丢了就能立刻 fail。 - 每月盯一下 Enhancements 报告。每种类型的 valid items 计数就是「回归溜过了 CI」的早期预警信号。
怎么确认修好了
- 对同一个 URL 重跑 Rich Results Test。现在应该显示该类型 eligible 且无报错。这是 ground truth——它反映 Googlebot 真实抓取并渲染的结果。
view-source线上页面,确认<script type="application/ld+json">block 在、能解析成 JSON、之前缺的字段已经有值。- 在 Search Console 里对抽样页用 URL Inspection,点 “Test live URL”,再点 “Request indexing”。Enhancements 计数会随 Google 重爬重新校验——红色数字掉下来预期要 1-3 周,但 live test 当下就能确认修没修好。
FAQ
Q:坏的 JSON-LD 会影响排名吗? A:影响 rich result 资格,不直接影响排名。蓝链结果还在,只是丢掉了对应的富媒体展示(面包屑路径、商品价格/星级、视频缩略图等)。商品、食谱、活动这种垂类损失明显。
Q:我的报错在 FAQPage 上,需要修吗?
A:不用。截至 2026 年 6 月,Google 不再渲染 FAQ rich result(该功能 2026 年 5 月 7 日下线,6 月又从 Rich Results Test 和 FAQ 报告里撤掉了 FAQ 支持)。FAQPage 标记仍是合法 Schema.org,留着无害,但换不来任何 SERP 富媒体展示,所以别花时间去「修」它。把精力放在 Article、BreadcrumbList 以及仍能产生 rich result 的商品/食谱/活动类型上。
Q:暂时修不好,要不要把整个 JSON-LD 删掉?
A:对仍能换来 rich result 的类型,要删——带病上线比不上线更坏,因为 Google 会记录失败。先删,离线修好,再上回去。对已经废弃的类型(FAQPage、HowTo),从 SEO 角度没什么可删的,那段标记是惰性的。
Q:修完了 Enhancements 还在显示 invalid,多久能清? A:Search Console 跟着 Google 重爬刷新,预期 1-3 周。别干等——对抽样 URL 跑一次 Rich Results Test 当下就能告诉你修好没有。
Q:Rich Results Test 显示 Eligible 但 Google 不展示 rich result。 A:Eligible 是必要不充分。Google 还看内容质量、新鲜度、每次查询的意图,也可能就是选择不渲染这个富媒体。先确认该类型是 Google 仍然支持的(查 structured data gallery)再去怀疑有 bug。
Q:一页多个 JSON-LD block 可以吗?
A:可以。一个 Article + 一个 BreadcrumbList + 一个 WebSite 是标准做法,各放在自己的 <script> tag 里。但不要同一个 @type 输出多个值冲突的 block,Google 可能任选一个或全部忽略。
Q:到底该信哪个工具——Rich Results Test 还是 Schema Markup Validator? A:两个都用,各管一摊。Rich Results Test 回答「这能不能拿到 Google rich result」;Schema Markup Validator 回答「这在 Schema.org 语法上对不对」,覆盖全部 800+ 类型,包括 Google 不理会的那些。用 validator 抓语法/类型 bug,用 Rich Results Test 确认 SERP 资格。