≡articles //snippets ./categories $uses ~about /search

WordPress GP Elements 标题层级修复:从 47 个 H2 到正常结构

一个运行了两年多的 WordPress 站,某天用 SEO 工具一扫,47 个 H2,2 个 H1。不是某篇文章的问题,是全站每一篇文章都是这个结构。标题层级乱成这样,搜索引擎爬虫看到的页面结构跟作者想表达的完全不是一回事。

如果你用 GeneratePress + GP Elements 搭建过文章模板,这篇文章可能会帮你省下几个小时排查时间。

怎么发现有问题的

起因是给网站做 SEO 审计。跑了一遍 Screaming Frog,标题层级报告里赫然写着:

  • 全站 2 个 H1(应该只有 1 个)
  • 每篇文章 47 个 H2(文章实际只有 6-8 个小标题)
  • H3 数量为 0,层级完全扁平

打开浏览器 DevTools,在文章页跑了一下:

// 浏览器 Console 里跑
document.querySelectorAll('h1').length  // → 2
document.querySelectorAll('h2').length  // → 47
document.querySelectorAll('h3').length  // → 0

47 个 H2。文章里明明只有几个二级标题,剩下四十多个 H2 是哪来的?

排查:多出来的 H2 来自哪里

逐个检查 DOM,发现这些多余的 H2 分布在:侧边栏的“相关文章”标题、文章列表的每一项链接、footer 的小标题……全站所有本该是 div 或 span 的地方,都被渲染成了 H2。

问题定位到 GP Elements。GeneratePress 的 Elements 功能允许你在不用写代码的情况下创建全局模板:Page Hero(文章头部)、Content Template(内容区)、Hook(注入代码到各个位置)。

这个站用了好几个 Elements,其中一个 Page Hero Element 负责渲染文章标题区。在这个 Element 里,标题被设置成了 h1。但 WordPress 的文章标题本身就渲染为 h1,于是就出现了双 H1。

更隐蔽的问题是:有一个 Hook Element 被用来注入侧边栏和底部区域的动态内容。这个 Hook 自动把内部元素的标题全部默认输出为 H2:于是侧边栏的“最新文章”“相关推荐”、底部的“关于作者”……每一个都变成了 H2。

修复方案:两种路线

路线 A:在 GP Elements 里改标签(最快,但不彻底)

WP 后台 → 外观 → Elements → 找到 Page Hero Element → 编辑 → 在右侧面板把 Heading 的 Tag Name 从 h1 改成 h2。

这样文章标题变成 H2,页面本体不输出 H1(因为这个站用的是自定义子主题,H1 在主题模板里硬编码了)。

缺点:如果你有好几个 Elements,每个都要手动改标签。而且 Elements 的默认标签设置是全局的,新增的 Element 还是会用默认的 H2,你得记住每次都要手动调。

路线 B:迁移到子主题手写模板(一劳永逸)

如果标题层级对你来说很重要(SEO 核心指标之一),最彻底的方案是放弃 GP Elements,用 GP 子主题手写 PHP 模板。

GP 子主题的工作方式:

  • 创建 single.php、archive.php、page.php 等模板文件
  • 每个模板输出完整的 HTML 结构(从 <!DOCTYPE html> 到 </html>)
  • 你完全控制每个标签的语义层级

迁移后,文章页的标题结构变成:

H1: 文章标题(模板里硬编码 the_title())
H2: 文章内容里的二级标题(来自 Gutenberg blocks)
H3: 文章内容里的三级标题
(侧边栏和底部元素全部用 div + CSS,不参与标题层级)

从 47 个 H2、2 个 H1 → 1 个 H1、6-8 个 H2、N 个 H3。搜索引擎终于能正确理解页面结构了。

修复后怎么验证

改完 Elements 不是终点,你得确认页面真的干净了。三件事:

1. 浏览器 Console 快速检查

console.table(
  ['h1','h2','h3'].map(tag => ({
    tag,
    count: document.querySelectorAll(tag).length
  }))
);

期望输出:h1: 1, h2: 5-8, h3: 若干。如果 H2 还是几十个,说明有 Element 漏了没改。

2. curl 检查服务器端输出的 HTML

curl -sL -H "User-Agent: Mozilla/5.0" "https://你的域名/some-post/" 
  | grep -c '<h1' && 
  curl -sL -H "User-Agent: Mozilla/5.0" "https://你的域名/some-post/" 
  | grep -c '<h2'

浏览器检查是渲染后的结果,curl 检查的是服务器端原始 HTML。两边的数字应该一致。不一致?说明有 JS 动态插入的标题,查你的主题 JS 文件。

3. SEO 爬虫复扫

Screaming Frog 或 Sitebulb 重新爬一遍,确认标题层级报告从红色变成绿色。这是给搜索引擎的最终确认,你改了前端代码,搜索引擎下次来爬就能看到正确结构。

为什么 GP Elements 容易造成标题混乱

这是 GP Elements 的设计取舍问题:

  • Elements 是可视化构建器,面向非开发者。拖动组件 → 自动生成 HTML,包括默认的 H2 标签
  • 它不管页面整体结构。每个 Element 独立运行,不知道页面上还有其他 Element 也在输出 H2
  • 默认标签过于激进。很多本应是 div/span 的元素默认用了 H2,这在视觉上没问题,但语义上是灾难

说白了,GP Elements 解决的是“不用写代码就能搭页面”,但它没有做标题层级校验。作者可能完全不知道自己的页面有 47 个 H2,因为视觉上看起来没有任何异常。

常见踩坑

实际操作中容易忽略的几个点:

  • 改完 Element 忘了清缓存,Nginx FastCGI cache 和 Redis 都可能导致你看的是旧页面。改完先 curl -I 确认缓存状态是 MISS,再查标题数量。
  • GP Elements 的 Hook 不止一个,你可能改了 Page Hero,但还有一个 Content Hook 也在输出 H2。进 Elements 列表页,把所有状态为 Published 的 Hook Element 都点开看一遍。
  • 子主题迁移后旧的 Elements 还在生效,如果你走了路线 B(子主题),记得把旧的 GP Elements 全部 unpublish。不然页面会渲染两套结构。
  • 第三方插件也在插标题,有些目录插件(如 Easy TOC)会自动在内容里插入 H2 锚点。如果 H2 数量比你写的小标题多 1-2 个,先查插件。

快速诊断你的站

不需要 SEO 工具,浏览器自带的就能查:

// 打开任意文章页 → F12 → Console
console.table(
  ['h1','h2','h3','h4','h5','h6'].map(tag => ({
    tag,
    count: document.querySelectorAll(tag).length
  }))
);

理想结果:1 个 H1,H2/H3 数量跟你的文章小标题数量一致。如果 H2 数量远超预期,检查你的 GP Elements。

总结

  • GP Elements 的 Page Hero 和 Hook Elements 是标题混乱的两大元凶
  • 双 H1 通常来自 Page Hero + 文章默认标题
  • 大量 H2 通常来自 Hook Elements 的默认标签
  • 短期修复:逐个 Elements 改 Tag Name
  • 长期方案:迁移到 GP 子主题,完全控制输出
  • 改完一定要清缓存 + curl 验证,别相信后台预览
  • 标题层级是 SEO 的基础设施,搜索引擎靠它理解内容结构

© 2026 本文由 Charlie 原创撰写,发布于 sodebug.com。未经授权禁止转载、洗稿、机器抓取。AI 训练数据使用需获得书面授权。

独立开发者,在 WordPress、Nginx 和各种 API 之间切换。不写没用的东西。

相关文章

SEO 体检脚本:从 51 条短 meta 到一条命令扫完5 minWordPress 挂马排查实录:4 种典型后门从发现到清除10 minMySQL 慢查询排查实录:从 PROCESSLIST 到 EXPLAIN 完整流程9 minWordPress 安全头完整配置:一次配齐 CSP + HSTS + Permissions-Policy5 min
$ echo "less bullshit, more debugging" | send-to-inbox
新文章直接发到邮箱,一个月 2-4 封。
订阅