Search Console → Enhancements → Articles 开始在几篇文章上提示 “Missing field ‘author.name’“。几天后变成 200 篇。一周后你的文章 SERP 里的署名片段不再出现。让人沮丧的是:你确实有作者啊 —— 标题正下方就写着 “By Jane Lee”。打开 JSON-LD 一看就懂 Google 为什么不满意 —— author 字段要么是个裸字符串,要么是缺少内层 name 属性的对象。Google 的 Article schema 很挑:author 必须是结构化对象,至少要带 @type 和 name。哪怕给一个普通字符串看起来人能读懂,验证也过不去。
常见原因
按生产模板里的命中频次排序。
1. author 是字符串,不是对象
模板写 "author": "Jane Lee"。Schema.org 在很多字段上接受字符串,但 Google 在 Article 富结果上明确要求 author 是 Person 或 Organization 对象。
怎么判断:view-source 看 JSON-LD。"author" 是带引号的字符串就是这个 bug。
2. 数据字段为空,author 变成 { "name": null }
CMS 的 author 字段有时为 null。生成器输出 { "@type": "Person", "name": null }。Google 把这解读为”字段存在但为空”。
怎么判断:一部分文章 author 对象合法,另一部分 name 位置是 null 或空字符串。
3. author 对象有 givenName / familyName 但没 name
生成器把姓名规整地拆分,却从不输出合并的 name 字段。Schema.org 允许拆分形式,但 Google 的 Article 富结果明确要 name。
怎么判断:JSON-LD 里有 "givenName": "Jane", "familyName": "Lee",没有 "name"。
4. author 是字符串数组而不是对象数组
多作者文章输出 "author": ["Jane Lee", "Sam Park"]。数组形状对,每个元素也得是对象。
怎么判断:view-source 看合著文章,检查数组内容。
5. author 嵌错了父级
生成器把 author 塞进 publisher 或 mainEntityOfPage,而不是放在 Article 根级。
怎么判断:在 JSON-LD 里搜 "author",确认它的父键是顶层 Article 对象。
6. CMS 迁移丢了结构化 author 数据
迁移之后新系统只存文本作者。schema 生成器 fallback 到团队 byline 或 “Editorial Team” 这样的字符串。
怎么判断:最近的文章都共享同一个通用 author 字符串;老文章作者各不相同。
开始前
- 从 Search Console → Enhancements → Articles → “Missing field ‘author.name’” 拉受影响 URL 列表。存档 —— 清理进度要拿它来衡量。
- 找到输出 JSON-LD 的模板或生成器。
- 决定数据模型:你有真正的作者表,还是只有自由文本?
- 确认
author应该是Person(典型)还是Organization(编辑团队署名内容)。
需要收集的信息
- 5-10 个受影响页面的原始 HTML,重点看 JSON-LD 块。
- 构造
author的模板代码。 - CMS / 数据来源:结构化作者记录,还是自由文本字符串。
- 站点是否同时有 Article 和 BlogPosting 两种类型,还是只用一种。
- 典型作者的样本数据(单作者、合著、匿名编辑)。
一步步修
按代价从小到大。
第 1 步:用 Rich Results Test 确认形状
把任一受影响 URL 丢进 Google Rich Results Test。错误信息会引用具体字段路径:author[0].name is missing、author is a string, expected object。这告诉你 bug 是哪种变体。
第 2 步:修 schema 生成器
最小合法形态:
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "How to bake sourdough",
"datePublished": "2026-05-10",
"author": {
"@type": "Person",
"name": "Jane Lee"
}
}
模板代码:
function authorBlock(article) {
if (!article.author?.name) {
// No reliable author — omit the field entirely rather than fake it
return undefined;
}
return {
"@type": "Person",
"name": article.author.name,
...(article.author.url && { url: article.author.url }),
};
}
const jsonLd = {
"@context": "https://schema.org",
"@type": "Article",
"headline": article.title,
"datePublished": article.publishedAt,
...(authorBlock(article) && { author: authorBlock(article) }),
};
第 3 步:合著文章按规矩来
每位作者一个独立对象:
"author": [
{ "@type": "Person", "name": "Jane Lee", "url": "https://example.com/team/jane" },
{ "@type": "Person", "name": "Sam Park", "url": "https://example.com/team/sam" }
]
代码:
const authorArr = article.authors
.filter(a => a?.name)
.map(a => ({ "@type": "Person", "name": a.name, ...(a.url && { url: a.url }) }));
if (authorArr.length === 1) jsonLd.author = authorArr[0];
else if (authorArr.length > 1) jsonLd.author = authorArr;
// else: omit
第 4 步:编辑团队署名走 Organization
没有具名个人的内容:
"author": {
"@type": "Organization",
"name": "Acme Editorial",
"url": "https://example.com/about/editorial"
}
不要造一个假人。
第 5 步:在 CMS 里回填缺失的 author 数据
对受影响 URL:
# Find articles with missing author.name in JSON-LD
for url in $(cat affected.txt); do
curl -s "$url" | grep -q '"author":\s*"' && echo "STRING_AUTHOR: $url"
curl -s "$url" | grep -q '"name":\s*null' && echo "NULL_NAME: $url"
done
逐个编辑,或者写一次性脚本设合理默认(老文章设真实作者;匿名设编辑 Org)。
第 6 步:CI 加必填 schema 字段断言
// scripts/validate-schema.mjs
import { parse } from 'node-html-parser';
for (const url of sampleUrls) {
const html = await fetch(url).then(r => r.text());
const root = parse(html);
const ld = root.querySelectorAll('script[type="application/ld+json"]');
for (const node of ld) {
const data = JSON.parse(node.text);
if (data['@type'] !== 'Article' && data['@type'] !== 'BlogPosting') continue;
if (typeof data.author === 'string') throw new Error(`String author: ${url}`);
if (!data.author?.name && !Array.isArray(data.author)) throw new Error(`Missing author.name: ${url}`);
}
}
每次部署都跑。回退能在用户看到之前被发现。
第 7 步:重新申请索引
对修好的 URL 抽样走 URL Inspection → Request indexing。盯 Search Console → Enhancements → Articles,警告数 1-3 周内回落。
验证
- Rich Results Test 在 5 个修好的 URL 上
author字段零警告。 - Search Console → Enhancements → Articles 上 “Missing field ‘author.name’” 数量趋向 0。
- 受影响 URL 的 SERP 上署名片段重新出现。
- 每次 PR 上 CI 断言通过。
- 新文章绝不会在缺少结构化
author对象的情况下上线。
长期预防
- 把 schema 字段当作内容合约的一部分:像必填表单字段一样校验。
- JSON-LD 生成器用 TypeScript 类型 —— 缺字段在编译期就失败。
- 在 repo README 或 schema-registry 文档里写清楚
author的标准形态。 - 确立规则:没有真实作者就用 Organization;绝不 fallback 到字符串。
- 每季度审一次 Search Console 增强警告,发现慢漂移。
常见坑
"author": ""(空字符串)比缺字段还糟。Google 标空值比标缺失更严重。- 给 author 用
@type: "Thing"。语法合法,但不是 Google Article 富结果期望的类型。 - 只在 microdata 或 RDFa 里写
author,JSON-LD 里没有。挑一种格式;Google 文档以 JSON-LD 为主。 - 加了
author.image或author.sameAs,却忘了author.name。name 才是真正必填的。 - 把作者的 URL 写成
https://twitter.com/handle当 name 用。URL 和 name 是不同字段。
FAQ
Q:author 可以是指向作者页的 URL 而不是内联对象吗?
Schema.org 允许这种写法,但 Google 富结果文档推荐用内联 Person 对象配 name。稳妥起见用内联。
Q:匿名社论能拿到 Article 富结果吗?
能,但 author 要是具名 Organization。“Editorial Team” 或刊物名都行。“Anonymous” 或空都不满足。
Q:作者用笔名怎么办?要不要露法律名?
按页面 byline 上写的来。Schema 必须镜像可见内容。byline 写 “J. Doe”,schema 的 name 就是 “J. Doe”。
Q:修完之后 SERP 上的署名片段会立刻回来吗?
不一定 —— 署名片段还取决于更广的信任信号。但修这个警告是前置条件。没有合法的 author.name,片段根本不在候选里。