Title 标签与 H1 不一致导致 Google 改写

`<title>` 和 `<h1>` 说的不是一件事,Google 哪个都不信,直接改写你的 SERP 标题。对齐两者并重新申请索引,就能把标题拿回来。

你的页面 <title>Best Wireless Headphones 2026 | Acme Reviews</title>,可见 <h1> 却是 “We tested 47 pairs of headphones so you don’t have to.”。Google 看到两个互相打架的信号——这页到底讲什么?于是自己改写 SERP 标题,通常换成你的 H1,或者从正文里裁出来的一截。点击率往下掉。

最快的修法:让 <title><h1> 讲同一件事、用同样的核心词(<title> 可以再加一个简短修饰词或品牌后缀),确认页面只有一个 <h1> 且其文本在服务端 HTML 里就有,然后对受影响的 URL 重新申请索引。改写通常在 2-3 次抓取以内停止。

这件事比以前更重要了。2025 年第一季度 Google 抽样改写了约 76% 的 title 标签;在被改的标题里,约 63% 删掉了品牌名,平均砍掉约 2.71 个词(SerpClix 研究数据,截至 2026 年 6 月仍是最常被引用的数字)。Google 没动的标题集中在 30-60 字符区间。所以一个干净、对齐、60 字符以内的标题就是你最好的防线。

Google 官方的 Influencing title links 文档列出了它生成 SERP 标题时会参考的来源:<title> 元素、页面上的主视觉标题、<h1> 及其他标题、og:title、大号或显眼的样式文本、指向本页链接的锚文本、以及 WebSite 结构化数据。这些信号一旦打架,Google 就自己拿主意——而且它几乎总是更信可见的 H1 而非 <title>,因为 H1 才是用户真正看到的。

你属于哪一类

Google 文档列了六种会触发改写的情形。把你的现象对到原因,直接跳到对应的修法。

你在 SERP 看到的现象可能的原因跳到
Google 显示你的 H1 而不是 title<title><h1> 不一致,Google 信 H1第 2-3 步
品牌后缀被删,其余保留标题太长,Google 砍掉 ” | Brand”第 4 步
SERP 标题是正文里的一句话没有明确的主标题 / H1 缺失或为空第 5-6 步
很多页面共用同一个泛标题微样板文本(模板化标题)第 2 步
标题正常但 curl 看 H1 区域是空的H1 在首次渲染后由 JavaScript 设置第 6 步
SERP 标题语言和页面不一样书写系统 / 语言不匹配第 6 步备注

常见原因

按频次排序。

1. CMS 里 title 字段和 H1 来源是两个字段

CMS 有 “SEO Title” 和单独的 “Headline” 两个字段。编辑只填 “Headline”,模板用 “SEO Title” 喂 <title>、用 “Headline” 喂 <h1>。从第一天起就漂。当 “SEO Title” 字段被留给像 “Article | Acme” 这样的模板默认值时,还会触发 Google 的”微样板文本”。

怎么判断:查三篇文章。<title><h1> 很少匹配,就是字段设计的根因。

2. 模板只给 <title> 加品牌后缀

<title> 变成 “How to Bake Sourdough | Acme Cooking”,<h1> 保持 “How to Bake Sourdough”。差距不大,但整串一长,Google 就先把品牌砍掉——删品牌正是 Google 最常做的一种改动(同一份 2025 年研究里约占被改标题的 63%)。

怎么判断<title> 以 ” | Brand” 或 ” - Brand” 结尾,<h1> 没有,且改写后的 SERP 标题里也没有品牌。

3. H1 是创意 / 标题党,<title> 是 SEO 优化过的

编辑团队写一句有冲击力的 H1 (“Why my sourdough finally stopped collapsing”)。SEO 团队把 title 改成关键词密集的 (“Sourdough Bread Recipe — Step-by-Step Guide”)。两边都是故意写成这样,互不相同。这对应 Google 的”标题不准确”触发条件:<title> 像个分类标签,跟页面真正可见的主题对不上。

怎么判断:H1 像博客标题,<title> 像分类页标题。两个独立看都不错;放一起搜索引擎犯糊涂。

4. 页面上有多个 H1

页面 hero 区有 <h1>Category Name</h1>,正文里又有 <h1>Article Title</h1>。这正是 Google 文档里说的”没有明确的主标题”——多个同等显眼的标题,Google 分不清哪个才是这一页的 H1。

怎么判断:DevTools 里跑 document.querySelectorAll('h1').length,大于 1 就是问题。

5. H1 是没有 alt 文本的图片

<h1><img src="/heading.svg"></h1>——可见标题是一张 SVG,没 alt。Google 拿不到 H1 的任何文本,只能 fallback 到 <title> 和正文——如果 <title> 上下文不足,就可能被改写。

怎么判断:view-source 找 <h1>,里面只有空 <img>,没有其他文本内容。

6. H1 在首次渲染后被 JavaScript 动态设置

HTML 响应里 <h1>Loading...</h1>,挂载后 JS 替换掉。Googlebot 大多会渲染页面,但渲染是分批排队的,可能先索引渲染前的 HTML;在那期间一个占位 H1 看起来就是坏的。

怎么判断curl 抓页面看 <h1>。如果是 “Loading…” 或空的,就是动态标题模式在作祟。也可以看 JavaScript 动态设置的标题未被索引

7. 标题和页面书写系统不同

<title> 是英文,但页面正文和 H1 是另一种语言(或反过来)。Google 把这标记为书写系统不匹配,换成跟页面主语言一致的标题。

怎么判断:比较 <title> 的文字脚本和渲染后正文的主导脚本。

开始前

  • 列出最近 30 天 Google 改写过标题的 10-20 个页面(Search Console 的 Performance 报告,按展示数过滤,再核对这些 URL 的 SERP 实际渲染)。
  • 看改写是否有规律(每次同一模式)还是随机。
  • 记下每个受影响 URL 当前的 <title><h1>
  • 决定策略:H1 跟 <title> 必须完全一致,还是 <title> 是 H1 加品牌后缀。

需要收集的信息

  • 驱动 <title><h1> 的 CMS 字段名。
  • 输出它们的模板代码,以及 og:title 的来源(Google 也会读它)。
  • 站点是否有给所有 <title> 加品牌后缀的全局变换。
  • 哪些页面有多个 <h1>(爬一次站,抽结构特征)。
  • 受影响 URL 的服务端渲染 HTML(不要靠 DevTools,它展示的是 hydration 后的状态)。

一步步修

按代价从小到大。

第 1 步:审一下当前状态

for url in $(cat affected-urls.txt); do
  html=$(curl -s "$url")
  title=$(echo "$html" | grep -oE '<title>[^<]+</title>' | head -1)
  h1=$(echo "$html" | grep -oE '<h1[^>]*>[^<]+</h1>' | head -1)
  echo "$url | $title | $h1"
done

输出拉进表格,一眼就能看出不一致集中在哪里。因为 Googlebot 也读 og:title,把它一起 grep 出来,确认它和 <title> 一致。

第 2 步:合并 CMS 字段

对应该永远一致的内容类型,把 “SEO Title” 和 “Headline” 合并成一个来源字段:

// content schema
title: z.string().min(20).max(60),  // single source, kept under the 60-char sweet spot

// template
<title>{article.title}{brandSuffix(article.section)}</title>
<h1>{article.title}</h1>

对故意要不同的内容类型(比如清单文),保留两个字段,但在 CI 里强制相似度检查(第 3 步)。

第 3 步:CI 里加一个相似度检查

function tokenJaccard(a: string, b: string): number {
  const toks = (s: string) => new Set(s.toLowerCase().match(/\w+/g) ?? []);
  const A = toks(a), B = toks(b);
  const inter = [...A].filter(x => B.has(x)).length;
  return inter / (A.size + B.size - inter);
}

for (const article of allArticles) {
  const score = tokenJaccard(article.title, article.h1);
  if (score < 0.5) {
    console.warn(`Low similarity: ${article.slug}: ${score.toFixed(2)}`);
  }
}

title 和 H1 实词共享率低于一半就让 build 失败(或警告)。得分 1.0 表示词集完全相同;“Sourdough Bread Recipe” 对 “Sourdough Bread Recipe — Step-by-Step Guide” 约为 0.6,属于健康范围。

第 4 步:长标题去掉品牌后缀

Google 在标题过长时会先砍品牌,那就抢在它前面自己砍。<title> 算上品牌后缀如果超过 60 字符左右,把后缀丢掉:

const FULL = `${article.title} | ${BRAND}`;
const titleTag = FULL.length > 60 ? article.title : FULL;

或者只在 <title> 留品牌、<h1> 不带:

<title>{article.title} | {BRAND}</title>
<h1>{article.title}</h1>  // brand omitted from H1, kept in template chrome only

哪个策略都行——一致就好。

第 5 步:强制一个页面只有一个 <h1>

这一步直接消掉 Google 的”没有明确主标题”触发条件。模板里:

{article && <h1>{article.title}</h1>}
{!article && pageType === 'category' && <h1>{categoryName}</h1>}
{/* no h1 in hero block — switch to h2 */}

修完爬一次站,断言每个页面正好一个 <h1>。注意:HTML5 允许多个 <h1> 是合法标记,但要让 SERP 标题可预期,你仍然需要一个占主导地位的标题。

第 6 步:H1 文本永远服务端渲染

不要在首次渲染之后用 JavaScript 设置 H1。把最终 H1 文本放进 HTML 响应里,<title>og:title 也都服务端渲染。如果标题以图片形式展示,用真正带文本的 <h1> 再用 CSS 做样式,别只靠 alt。多语言站点要确保 <title> 与页面正文语言一致,避免 Google 的书写系统不匹配改写。

第 7 步:对修好的 URL 重新申请索引

挑 Top URL,走 URL Inspection,点 “Request indexing”。截至 2026 年 6 月,Search Console 对此每个资源每天大约限 10-12 个 URL,且这只是个提示而非命令——Google 按自己的节奏重新抓取。批量更大时,重新提交受影响的 sitemap,让正常抓取捡到改动。每周跟 SERP 标题;通常修复后 2-3 次抓取以内改写就停止。

如何确认已修好

  • curl 任一受影响 URL,确认最终 <h1> 文本直接出现在响应里(不是 “Loading…”)。
  • 抽样 URL 的 title 与 H1 一致或明显在表达同一件事;og:title 也一致。
  • 没有 URL 含多个 <h1>(重跑一遍 DevTools 计数)。
  • 在 URL Inspection 里,渲染后的 HTML 显示你想要的 title 和单个 H1。
  • 接下来几周,Search Console 的 Performance 报告显示之前被改写的 URL 在恢复展示数 / 点击率,抽查实时 SERP 也显示的是你的标题(而非正文片段)。

长期预防

  • 选一个编辑策略:H1 和 <title> 一致,或 <title> = H1 + 受控的简短后缀。写下来。
  • CMS 里用单个字段做标题来源,由它派生 <title><h1>(和 og:title)。
  • 标题保持在 30-60 字符——Google 最少动手的区间。
  • 加 CI 断言:title/H1 相似度,以及单个 H1。
  • 避免动态 H1;非要做就服务端 ship 最终文本。
  • 每月审一次 Google 改写事件,在影响排名之前发现回退。

常见坑

  • 只在 <title> 上加 session ID 或 A/B 变体。编辑看不到,Google 看得到。
  • 把”Google 改写了我的标题”当随机事件放着。它非常确定——触发条件通常就是上面六种之一。
  • 用 CSS display:none 隐藏 <h1>,以为 Google 会忽略。Google 仍会解析为 H1,而且这种隐藏写法有风险。
  • 用带 role="heading"<div> 代替真正的 <h1> 元素。用真标签。
  • 五个词的 H1 配 16 个词的 <title>。长度和内容的落差本身就是不一致信号。
  • 忘了 og:title。它要是跟 <title> 矛盾,你就在下一层又造出了同样的不一致。

FAQ

Q:<title><h1> 必须一模一样吗?

可以不同,但大部分实词应该共享。常见做法:H1 = “Sourdough Bread Recipe”,<title> = “Sourdough Bread Recipe — Step-by-Step Guide | Acme”。加修饰词没问题;完全无关的 <title> 才是会被改写的那种。

Q:Google 显示我的 H1 当标题,而不是 <title>,为什么?

因为 Google 判定 H1 更能描述这一页。两者打架时,Google 几乎总是更信可见的标题。把 <title> 对齐到 H1 的核心词,它通常就会改回用你的 <title>

Q:可以没有 H1 吗?

技术上 HTML 合法,但 Google 把 H1 当作判断页面主题的多个信号之一。零 H1 让 Google 退回 <title>og:title 加正文,反而更容易被改写。

Q:Google 一定会改写不一致的标题吗?

不一定,但很常见——2025 年抽样里大约四分之三的标题被改写。跟 H1 不一致只是六个触发条件之一(半空、过时、不准确、微样板、没有明确主标题、语言不匹配)。修了能降低概率,但不代表 Google 永远不动你的 title。

Q:修好之后多久能换回真正的标题?

通常在改动页面被抓取 2-3 次以内。你可以用 URL Inspection 的 “Request indexing” 推一把(截至 2026 年 6 月,每个资源每天约限 10-12 个 URL),但它只是提示——Google 按自己的节奏重抓。

Q:H1 是 logo 图片,对 SEO 不好吗?

不好——Google 需要文本。用真正带文本的 <h1>,CSS 把 logo 样式做出来;或把 logo 移到兄弟元素,H1 保持文本。

标签: #SEO #排查 #title-tag #h1 #google-rewrite