主题 SEO
主题主要负责提供准确的页面标题、语义化正文,以及 Halo 未统一生成的规范链接和社交分享信息。站点管理员配置的 SEO 信息和内容摘要由 Halo 注入,不应在主题中重复实现。
设置页面标题
每个可索引页面都应有一个描述当前内容的 <title>。详情页和归档页通常将当前内容放在前面,站点名称放在后面:
作者归档页可以使用 author.spec.displayName。文章归档、分类列表和标签列表等固定页面应使用主题的国际化消息生成标题,不要把一种语言直接写入公共布局。
公共布局可以提供站点标题作为默认值,但具体模板应覆盖它。最终 HTML 中只能有一个 <title>,页面主标题也应与它表达相同的内容。
使用 Halo 注入的元数据
Halo 会在模板渲染期间向 <head> 注入以下信息:
因此,不要在主题中再次使用 site.seo.description 或 site.seo.keywords 生成同名 <meta>。插件和 Console 的代码注入也可以修改 <head>,排查问题时应检查最终响应,而不是只看主题源码。
Halo 仍会按设置输出 keywords,但主流搜索引擎通常不再使用该字段,主题无需额外处理。
运维人员可以通过 halo.theme.generator-meta-disabled=true 关闭 generator meta,主题不应依赖该标签判断 Halo 版本。
通过主题设置控制扩展标签
Halo 不会为所有页面统一生成 canonical、Open Graph、Twitter Card 或结构化数据。这些标签也可能由插件提供,因此主题不应在无法关闭的情况下固定输出。主题提供这些能力时,建议在 settings.yaml 中至少分别提供“页面元数据”和“结构化数据”开关:
如果站点已经通过插件提供对应标签,用户可以关闭主题中的选项。新增或修改设置项后,需要在 Console 的主题详情中重载主题配置,完整定义方式参考设置选项。
将 canonical、Open Graph 和 Twitter Card 集中在一个公共 head 片段中,并使用设置项保护。以下是文章页的最小示例:
site.url 必须是站点真实的外部访问地址。分页归档不能直接复用第一页的 canonical;应为当前分页生成正确地址,或者暂不输出该标签。Open Graph 的基本字段和取值可参考 The Open Graph protocol。
可选的结构化数据
文章主题可以在 theme.config.seo.enable_structured_data 为 true 时提供 BlogPosting JSON-LD,包括标题、规范地址、作者、发布时间、修改时间和图片。结构化数据必须与页面可见内容一致,且输出必须是有效 JSON;由插件提供时应关闭主题中的对应选项。
添加后使用 Google 富媒体搜索结果测试 和 Schema.org Validator 验证;完整字段参考 Google Article 文档 和 Schema.org BlogPosting。
验证最终结果
在已安装并启用主题的 Halo 上检查实际响应:
至少确认:
- 首页、文章、单页面和各归档页只有一个准确且不重复的标题。
- 文章、单页面、分类和标签的描述来自对应内容,未意外退回站点通用文案。
- 未开启禁止抓取时没有意外的
noindex。 - 分别开关主题的 SEO 设置,关闭后不再输出对应标签,开启后也没有与插件产生重复标签。
- canonical 是当前页面的绝对公开地址;社交图片也能从公网访问。
- 自定义模板、分页页和插件页面没有继承错误的标题或规范地址。
搜索引擎可能根据页面内容改写标题或摘要,正确的标签也不保证展示富媒体结果。标题和摘要的编写原则可参考 Google 标题链接和摘要文档。