结构化答案
Docsbook 会为每个文档页面写入一个 <script type="application/ld+json"> 元素。它包含一个 schema.org @graph ——一个链接对象数组——而不是多个单独的脚本标签,因此页面上的每个对象都共享同一个上下文,并可通过 @id 相互引用。
本页面准确列出了该图中包含的内容、每个对象要出现时 Markdown 必须满足的条件,以及失败时的表现。
图中有什么,以及是什么让它启用#
| 对象 | 出现条件 | 条件 |
|---|---|---|
Organization |
始终 | 项目所有者,其中 sameAs 指向 GitHub 账户;当工作区有 logo 时也包含它 |
TechArticle |
始终 | 页面本身:headline、name、description、url、inLanguage、datePublished、dateModified、author、publisher、mainEntityOfPage |
BreadcrumbList |
始终 | 从工作区主页到该页面的路径 |
Person 作为 author |
启用 GEO | 前置元数据中的 author:;否则使用修改该文件的最后一次提交的作者。关闭 GEO 时,author 是指向 Organization 的 @id 引用 |
speakable |
启用 AEO | 无条件添加到 TechArticle 内 |
FAQPage |
启用 AEO | 页面至少生成一个问题及其答案 |
HowTo |
启用 AEO | 页面至少生成一个包含三个或更多步骤的操作流程 |
SoftwareApplication 不属于此图。Docsbook 会在自己的营销页面上生成它,而不会在客户文档上生成——如果你读过关于我们的竞品对比并看到相反的说法,那么该类型实际存在于那里。
日期来自文件的 Git 历史,而不是前置元数据:datePublished 和 dateModified 均从最近一次修改该文件的提交中读取。尚无提交历史的页面不会携带这两个键,而不是使用虚构的日期。
什么样的 Markdown 结构会生成 FAQPage?#
满足以下任一条件时,一个章节会变成问题:
- 文本匹配
FAQ、Frequently asked questions或俄语Частые вопросы/Вопросы и ответы/Часто задаваемые的 H2(不区分大小写)。其下的每个 H3 都会变成一个问题,无论其末尾是否带有问号。 - 文档中任意位置以
?结尾的 H3,无论它所属的章节是什么。
答案是从该 H3 到下一个标题之间的所有非空行。行内 *、_ 和反引号字符会被去除。内容组件标记(<!-- widget:accordion --> 及其结束标记)会被跳过,而不会被吞入答案,因为手风琴组件通常用于编写 FAQ。
然后按以下顺序应用限制:为每个缺少末尾 ? 的问题追加一个;每个答案截取至 1,000 个字符;如果问题不超过 3 个字符或答案不超过 10 个字符,则丢弃该问答对;页面最多保留 20 个问题。
## FAQ
### Does a custom domain change my page URLs
Yes. Every canonical URL, sitemap entry and breadcrumb item moves to the new host on the next render.
### How long does the certificate take
Usually under a minute after the CNAME resolves.不是问题且不在 FAQ 章节中的 H3 不会生成任何内容。## Setup 下的 ### Install the CLI 会被正确忽略。
什么样的 Markdown 结构会生成 HowTo?#
以下三个条件必须同时满足:
- 以
How to开头的 H1、H2 或 H3 标题——或者俄语Как,其中下一个字符不能是字母或数字,因此Каким образом不匹配。 - 其后紧跟一个编号列表——
1.或1)均可。 - 列表至少包含 3 个步骤。
每个编号列表项都会成为一个 HowToStep。其 name 是第一句话,在单词边界处截断至 80 个字符并添加省略号;其 text 是整个列表项,最多 1,000 个字符。链接会被展平为其锚文本,行内强调格式会被移除。围栏代码块中的内容会被完全忽略,因此示例中的编号列表不会变成操作步骤。
一个操作流程最多包含 20 个步骤,一个页面最多包含 5 个 HowTo 对象。
步骤器小部件会被视为编号列表。在 <!-- widget:stepper --> 区域内,每个标题都会开启下一个步骤,无论其级别如何——但只有在由 How to / Как 标题引入该区域时,该区域才会成为一个 HowTo。位于 # Quick start 下方的步骤器不会生成任何内容。
## How to move your docs to a custom domain
1. Open the admin panel and select **Custom Domain**.
2. Enter `docs.example.com` and save.
3. Add the CNAME record the panel shows to your DNS provider.两个步骤不会生成任何内容。如果操作流程确实只有两个步骤,这就是正确结果——不要为了达到阈值而填充列表。
实际生成的 JSON-LD 内容#
这是 Docsbook 自身提取器对上面两个 Markdown 块运行后的输出:
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Does a custom domain change my page URLs?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes. Every canonical URL, sitemap entry and breadcrumb item moves to the new host on the next render."
}
},
{
"@type": "Question",
"name": "How long does the certificate take?",
"acceptedAnswer": { "@type": "Answer", "text": "Usually under a minute after the CNAME resolves." }
}
]
},
{
"@type": "HowTo",
"name": "How to move your docs to a custom domain",
"step": [
{ "@type": "HowToStep", "position": 1, "name": "Open the admin panel and select Custom Domain.", "text": "Open the admin panel and select Custom Domain." },
{ "@type": "HowToStep", "position": 2, "name": "Enter docs.example.com and save.", "text": "Enter docs.example.com and save." },
{ "@type": "HowToStep", "position": 3, "name": "Add the CNAME record the panel shows to your DNS provider.", "text": "Add the CNAME record the panel shows to your DNS provider." }
]
}
]
}请注意提取器对问题标题所做的处理:它追加了 Markdown 中省略的 ?。这就是为什么即使你将其写成陈述句,以问题形式表述的 H3 在标记中读起来仍然正确。
面包屑导航包含的内容#
导航路径由工作区主页 → 项目主页 → 每个路径段对应的一个项目组成。每个路径段的 name 都会转换为便于人类阅读的形式——去掉 .md 扩展名,将连字符和下划线转换为空格,并将每个单词首字母大写——而其 item URL 则使用与页面的 <link rel="canonical"> 相同的规范 URL 构建器生成,因此两者绝不会指向不同的主机。在翻译后的语言环境中,导航路径的 URL 也会使用该语言环境表示。
{
"@type": "BreadcrumbList",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "acme", "item": "https://acme.docsbook.io" },
{ "@type": "ListItem", "position": 2, "name": "Acme Handbook", "item": "https://acme.docsbook.io/handbook" },
{ "@type": "ListItem", "position": 3, "name": "Guides", "item": "https://acme.docsbook.io/handbook/guides" },
{ "@type": "ListItem", "position": 4, "name": "Custom Domains", "item": "https://acme.docsbook.io/handbook/guides/custom-domains" }
]
}Google 要求每个 ListItem 都包含 position、name 和 item,并且列表中至少包含两个项目(Google,面包屑导航);项目根目录下的页面恰好会生成两个主页项目,这也是文档规定的最低要求。
关于 speakable 的说明#
启用 AEO 后,TechArticle 获得:
"speakable": {
"@type": "SpeakableSpecification",
"cssSelector": [".tldr", "article > p:first-of-type", "h1"]
}schema.org 将 SpeakableSpecification 定义为表示“文档中被特别标记为适合朗读的部分”(schema.org)。选择器列表按优先顺序排列:如果启用了 GEO,则优先使用 GEO TL;DR 区块,然后是文章的第一段,最后是 H1。实际结果是,读者首先看到的内容也会被机器视为摘要——如果页面以背景介绍而非答案开头,就会将背景介绍声明为摘要。
标记错误时会发生什么#
Docsbook 不会在发布前验证图谱。渲染路径中没有模式检查器,而 audit_geo — 用于检查爬虫访问、服务器端渲染和 llms.txt 的工具 — 完全不会检查 JSON-LD。提取器生成的内容会原样出现在页面上。有四种值得了解的失败模式:
- 检测器没有匹配到任何内容。 这是最常见、也最不易察觉的结果:AEO 已启用,页面上有一个看起来像 FAQ 的部分,却没有出现任何
FAQPage。几乎总是标题级别的问题 — 检测器读取 H2 部分和 H3 问题,因此使用 H3 部分和 H4 问题编写的 FAQ 不会产生任何结果。 - 检测器匹配了过多内容。 任何以
?结尾的 H3 都会在文档中的任何位置成为 FAQ 问题,包括正文中的反问式标题。结果是有效的标记,却描述了一个并非 FAQ 的页面;这属于策略问题,而不是语法问题 — Google 的指南要求“您的结构化数据必须真实反映页面内容”(Google)。将标题改写为陈述句后,它就不会再匹配。 - 答案中的原始 HTML 会破坏区块。 答案文本会逐字复制到 JSON 中。FAQ 答案中的字面
</script>序列会提前结束 JSON-LD 元素,之后的所有对象都会丢失。不要在 FAQ 答案中使用原始 HTML;请使用页面其余部分所使用的 Markdown。 - 页面通过自定义域名提供服务。 使用自有域名的工作区会通过不同的路径进行渲染,该路径只输出一个单独的
TechArticle,不输出其他内容 — 没有面包屑、没有FAQPage、没有HowTo、没有speakable,无论 AEO 开关显示什么。在断定检测器失败之前,请先在*.docsbook.io地址上进行验证。
请使用 Google 的富媒体搜索结果测试或 Schema 标记验证工具进行验证。请注意,绿色结果如今意味着什么,以及不意味着什么:BreadcrumbList 仍是受支持的富媒体搜索结果,而 FAQPage 和 HowTo 虽然是有效的 schema.org,却已不再由 Google 渲染 — 请参阅 AEO 的限制。
限制与未解决的问题#
TechArticle不是 Google 为文章富结果命名的三种类型之一。Google 的文档指出:“文章对象必须基于以下 schema.org 类型之一:Article、NewsArticle、BlogPosting”(Google,文章)。TechArticle是Article的 schema.org 子类型——“技术文章 - 示例:操作方法(任务)主题、分步说明、程序性故障排除、规格说明”(schema.org)——也是对文档页面的准确描述。Google 是否将子类型视为符合文章富结果条件,相关文档同样没有明确说明。我们选择了准确性,而不是妄加猜测。- FAQ 和 How-to 检测器仅识别英语和俄语。章节标题和操作动词会针对这两种语言进行匹配。德语或日语 FAQ 页面不会生成任何
FAQPage,除非其 H3 标题以?结尾。 - 答案仅限正文内容。问题标题与下一个标题之间的所有内容会被连接起来,并在 1,000 个字符处截断——表格、代码块和图像会以其原始源代码的形式出现在答案文本中,或者在中途被截断。请将 FAQ 答案控制在几句话以内。
- 任何地方都不会报告生成内容的数量。没有任何面板、日志或 API 会告诉你某个页面生成了多少个
FAQPage问题或HowTo对象。查看源代码,或使用验证器。