你的页面 <title>Best Wireless Headphones 2026 | Acme Reviews</title>,可见 <h1> 却是 “We tested 47 pairs of headphones so you don’t have to.”。Google 看到两个互相打架的信号 —— 这页到底是讲什么的?哪个都不用,干脆把 SERP 标题改写成第二段里随便裁出来的一截。点击率往下掉。这是 Google 标题被改写的最常见且最可控的原因之一 —— 跟很多排名问题不同,这个完全在你掌控之内。
常见原因
按频次排序。
1. CMS 里 title 字段和 H1 来源是两个字段
CMS 有 “SEO Title” 和单独的 “Headline” 两个字段。编辑只填 “Headline”,模板用 “SEO Title” 喂 <title>、用 “Headline” 喂 <h1>。从第一天起就漂。
怎么判断:查三篇文章。<title> 和 <h1> 很少匹配,就是字段设计的根因。
2. 模板只给 <title> 加品牌后缀
<title> 变成 “How to Bake Sourdough | Acme Cooking”,<h1> 保持 “How to Bake Sourdough”。差距不大,但 Google 把附加到长标题上的品牌后缀视为用户不友好的噪音。
怎么判断:<title> 以 ” | Brand” 或 ” - Brand” 结尾;<h1> 没有。
3. H1 是创意 / 标题党,<title> 是 SEO 优化过的
编辑团队写一句有冲击力的 H1 (“Why my sourdough finally stopped collapsing”)。SEO 团队把 title 改成关键词密集的 (“Sourdough Bread Recipe — Step-by-Step Guide”)。两边都是故意写成这样,互不相同。
怎么判断:H1 像博客标题,<title> 像分类页标题。两个独立看都不错;放一起搜索引擎犯糊涂。
4. 页面上有多个 H1
页面 hero 区有 <h1>Category Name</h1>,正文里又有 <h1>Article Title</h1>。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 动态设置的标题未被索引。
开始前
- 列出最近 30 天 Google 改写过标题的 10-20 个页面(Search Console → Performance,按展示数过滤,再核对 SERP 实际渲染)。
- 看改写是否有规律(每次同一模式)还是随机。
- 记下每个受影响 URL 当前的
<title>和<h1>。 - 决定策略:H1 跟
<title>必须完全一致,还是<title>是 H1 加品牌后缀。
需要收集的信息
- 驱动
<title>和<h1>的 CMS 字段名。 - 输出它们的模板代码。
- 站点是否有给所有
<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
输出拉进表格。一眼就能看出不一致集中在哪里。
第 2 步:合并 CMS 字段
对应该永远一致的内容类型,把 “SEO Title” 和 “Headline” 合并成一个来源字段:
// content schema
title: z.string().min(20).max(65), // single source
// template
<title>{article.title}{brandSuffix(article.section)}</title>
<h1>{article.title}</h1>
对故意要不同的内容类型(比如清单文),保留两个字段,但在 CI 里强制相似度检查。
第 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 失败(或警告)。
第 4 步:长标题去掉品牌后缀
<title> 算上品牌后缀如果超过 60 字符左右,把后缀丢掉:
const FULL = `${article.title} | ${BRAND}`;
const titleTag = FULL.length > 65 ? article.title : FULL;
或者让两边都带品牌:
<title>{article.title} | {BRAND}</title>
<h1>{article.title}</h1> // brand omitted from H1, kept in template chrome only
哪个策略都行 —— 一致就好。
第 5 步:强制一个页面只有一个 <h1>
模板里:
{article && <h1>{article.title}</h1>}
{!article && pageType === 'category' && <h1>{categoryName}</h1>}
{/* no h1 in hero block — switch to h2 */}
修完爬一次站,断言每个页面正好一个 <h1>。
第 6 步:H1 文本永远服务端渲染
不要在首次渲染之后用 JavaScript 设置 H1。要么 HTML 里就有最终 H1,要么接受 Google 可能用别的信号代替。
第 7 步:对修好的 URL 重新申请索引
挑 Top 10-20 个 URL,走 URL Inspection → Request indexing。每周跟 SERP 标题;通常修复后 2-3 次抓取以内改写就停止。
验证
- 抽样 URL 的 title 与 H1 一致或明显在表达同一件事。
- 没有 URL 含多个
<h1>。 - Search Console 上 Google 改写标题的数量逐周下降。
- 之前被改写过的 URL 点击率回稳或回升。
curl任一 URL,响应里直接含最终 H1 文本。
长期预防
- 选一个编辑策略:H1 和
<title>一致,或<title>= H1 + 受控后缀。写下来。 - CMS 里用单个字段做标题来源,由它派生
<title>和<h1>。 - 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>。长度差本身就是 Google 用来判断不可信的信号。
FAQ
Q:<title> 和 <h1> 必须一模一样吗?
可以不同,但大部分实词应该共享。常见做法:H1 = “Sourdough Bread Recipe”,<title> = “Sourdough Bread Recipe — Step-by-Step Guide | Acme”。加修饰词没问题;完全无关的 <title> 不行。
Q:可以没有 H1 吗?
技术上 HTML 合法,但 Google 把 H1 当作判断页面主题的多个信号之一。零 H1 让 Google 退回 <title> 加正文,反而更容易被改写。
Q:Google 一定会改写不一致的标题吗?
不。Google 判定 <title> “与页面不一致”时才改。跟 H1 不一致只是触发条件之一。修了不代表 Google 永远不动你的 title —— 只是降低被改写的频率。
Q:H1 是 logo 图片,对 SEO 不好吗?
不好 —— Google 需要文本。用真正带文本的 <h1>,CSS 把 logo 样式做出来;或把 logo 移到兄弟元素,H1 保持文本。