Search Console “增强项”报告里出现红字结构化数据警告,比如 “Missing field ‘image’”、“Invalid value in field ‘datePublished’”、“Either ‘author’ or ‘publisher’ must be specified”。这不会直接影响收录,但会让你失去 rich snippet —— 没作者卡、没星级、没 FAQ 折叠展示。CTR 通常会因此跌 10-30%。
修法是逐字段对照 Schema.org 标准 + Google 自己的结构化数据要求。
常见原因
1. 必填字段缺失
最常见的几个:
| 类型 | 必填 (Google) | 常被遗漏 |
|---|---|---|
Article / BlogPosting | headline, image, datePublished, author | image, author |
Product | name, image, offers (含 price 和 priceCurrency) | offers.priceCurrency |
Recipe | name, image, recipeIngredient, recipeInstructions | recipeInstructions |
FAQPage | mainEntity 数组,每项含 name 和 acceptedAnswer.text | acceptedAnswer.text |
Event | name, startDate, location | location 格式 |
如何判断:用 Rich Results Test 输入 URL,会显示具体哪个字段缺。
2. 类型选错(Article vs BlogPosting vs NewsArticle)
Article 是基类,BlogPosting 是博文,NewsArticle 是新闻。同页同时声明两个会冲突。新闻媒体网站用 NewsArticle 才能进 Google News;个人博客用 BlogPosting;一般技术指南用 Article 即可。
3. 日期格式错
Google 要求 ISO 8601:
"datePublished": "2026-05-21T10:00:00Z" // 对,带时区
"datePublished": "2026-05-21" // 也对
"datePublished": "2026/05/21" // 错
"datePublished": "May 21, 2026" // 错
"datePublished": "2026-05-21T10:00:00" // 错,缺时区
4. image 字段格式
image 不能只是字符串 URL(在某些类型里),要是 ImageObject:
// 简单(部分场景能用)
"image": "https://yourdomain.com/cover.jpg"
// 完整推荐
"image": {
"@type": "ImageObject",
"url": "https://yourdomain.com/cover.jpg",
"width": 1200,
"height": 630
}
且 image URL 必须绝对路径(含 https://),不能是 /cover.jpg。
5. author 写成裸字符串
// 错
"author": "Jane Doe"
// 对
"author": {
"@type": "Person",
"name": "Jane Doe",
"url": "https://yourdomain.com/about"
}
6. JSON-LD 语法错误(多了逗号、引号配错)
JSON-LD 必须是合法 JSON,trailing comma 会让整段失效。Schema.org 验证器和 Rich Results Test 都会报”Parsing error”。
最短修复路径
Step 1:用 Rich Results Test 看具体报错
https://search.google.com/test/rich-results
输入线上 URL,会看到:
- 哪些 schema 类型被识别
- 每个字段的值
- 红字警告 = 必填缺失或值无效
- 黄字提示 = 推荐字段缺失
记下报警字段名。
Step 2:到对应的 Schema.org 类型页对照
例如报警是 Article 类型的 image:
https://schema.org/Article (看 Article)
https://developers.google.com/search/docs/appearance/structured-data/article (看 Google 的额外要求)
确认这个字段是必填、推荐、还是你选了错的类型。
Step 3:JSON-LD 用一个 helper 统一生成
// src/lib/jsonld.js
export function articleJsonLd({ title, slug, image, publishedAt, modifiedAt, author }) {
const url = `https://yourdomain.com/articles/${slug}/`;
return {
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": title,
"image": {
"@type": "ImageObject",
"url": image.startsWith("http") ? image : `https://yourdomain.com${image}`,
"width": 1200,
"height": 630
},
"datePublished": new Date(publishedAt).toISOString(),
"dateModified": new Date(modifiedAt || publishedAt).toISOString(),
"author": {
"@type": "Person",
"name": author?.name || "AI Productivity Guide Team",
"url": author?.url || "https://yourdomain.com/about"
},
"publisher": {
"@type": "Organization",
"name": "Your Site",
"logo": {
"@type": "ImageObject",
"url": "https://yourdomain.com/logo.png",
"width": 600,
"height": 60
}
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": url
}
};
}
模板里:
---
import { articleJsonLd } from "../lib/jsonld.js";
const ld = articleJsonLd(Astro.props);
---
<script type="application/ld+json" set:html={JSON.stringify(ld)} />
Step 4:CI 加 JSON-LD 校验
// scripts/check-jsonld.mjs
import fg from "fast-glob";
import fs from "node:fs";
const issues = [];
for (const f of fg.sync("dist/**/*.html")) {
const html = fs.readFileSync(f, "utf8");
const blocks = [...html.matchAll(/<script[^>]+ld\+json[^>]*>([\s\S]+?)<\/script>/g)];
if (blocks.length === 0) { issues.push(`NO JSON-LD: ${f}`); continue; }
for (const [, body] of blocks) {
try {
const data = JSON.parse(body);
if (!data["@type"]) issues.push(`MISSING @type: ${f}`);
if (data["@type"] === "BlogPosting") {
if (!data.headline) issues.push(`MISSING headline: ${f}`);
if (!data.image) issues.push(`MISSING image: ${f}`);
if (!data.datePublished) issues.push(`MISSING datePublished: ${f}`);
if (!data.author) issues.push(`MISSING author: ${f}`);
}
} catch (e) {
issues.push(`INVALID JSON: ${f} — ${e.message}`);
}
}
}
if (issues.length) { console.error(issues.join("\n")); process.exit(1); }
Step 5:部署后 Search Console “验证修复”
到对应增强项报告 → 点 “验证修复”。Google 7-14 天复审。
可以同时挑 5-10 个最重要 URL,在 URL 检查里 “请求编入索引” 加速。
预防建议
- JSON-LD 永远用一个 helper 生成,杜绝手写
- 同一页同类型 schema 只能出现 1 次,不要 Article + BlogPosting 同时声明
- 日期一律
new Date(...).toISOString(),杜绝字符串拼接 - 所有 URL 字段(image url、author url、publisher logo url)必须绝对路径含 https://
- 上线前必跑 Rich Results Test,绿勾才能合并
- CI 解析每个 HTML 的 JSON-LD,必填字段缺失直接 fail