The title Google shows in the SERP isn’t what you wrote in <title> — it’s the page H1, the first paragraph, the site name concatenated, or some text Google decided better matches the query. Google’s documentation says about 60% of SERP titles use your <title>; the other 40% are rewritten.
To push the rewrite rate below 15%, fix the specific triggers below.
Common causes
1. <title> too long
Desktop SERP title width is ~580px, which fits 50-60 English characters or 28-32 CJK characters. Overlong titles get truncated, and Google often rewrites rather than show a half-cut sentence.
How to confirm:
curl -sL https://yourdomain.com/page | grep -oE '<title>[^<]+</title>'
# Count characters
2. Keyword stuffing / pipe stacks
"AI tools | ChatGPT | Claude | Best of 2026 | Must-have for devs" is recognized as SEO optimization. Google rewrites it to H1 + site name.
3. <title> doesn’t match page intent
<title> promises “Complete Guide” but the body has 300 words. Google extracts a body sentence that better matches the query. Or the keyword in your title doesn’t appear in the body at all.
4. No H1, or multiple H1s
Google relies heavily on H1 as a title signal. Zero H1s / multiple H1s → it synthesizes a title from other sources, typically site name + first paragraph.
How to confirm:
curl -sL https://yourdomain.com/page | grep -oE '<h1[^>]*>[^<]+</h1>'
# Want exactly 1 line
5. <title> and H1 say different things
If they convey completely different meanings, Google trusts H1 over title.
6. Many pages share an identical <title> template
"Blog - Company Name" repeated across the site → Google needs another signal to distinguish and rewrites.
Shortest path to fix
Step 1: Identify which URLs were rewritten
Search Console → Performance → “Pages” sort by impressions descending. Take the top 20 URLs and for each:
# Your <title>
curl -sL "https://yourdomain.com/url" | grep -oE '<title>[^<]+</title>'
# Google search
site:yourdomain.com/url
Compare what’s shown in the SERP to the source title. Different = rewritten.
Step 2: Rewrite titles using the template
[intent or primary keyword] + [unique qualifier/number/year] + [brand (optional, at end)]
Bad → good:
| Bad | Good |
|---|---|
AI tools | ChatGPT | Claude | Best 2026 | 12 AI tools I actually paid for in 2026, ranked by hours saved per week |
Blog - MyCompany | Deploying Astro to Vercel: The Complete 2026 Guide |
Complete Guide (no topic) | Complete hreflang Setup Guide: 6 Common Errors + Fix Paths |
Character budget:
- English: 50-60 characters
- CJK: 26-30 characters with punctuation
Primary keyword in the first 30 characters so it survives mobile truncation.
Step 3: Ensure exactly one H1 per page
# Site-wide scan
for f in $(find dist -name "*.html"); do
count=$(grep -oE '<h1[\s>]' "$f" | wc -l)
[ "$count" != "1" ] && echo "$f: H1=$count"
done
Fix:
<header><h1>SiteName</h1></header>→<header>SiteName (no h1)</header>- Article body always has 1
<h1>[Article Title]</h1> - H1 and
<title>express the same intent (not necessarily word-for-word, but semantically aligned)
Step 4: Make every page’s title template unique
In your CMS / static site generator template:
---
const { title, brand = "MyCompany" } = Astro.props;
const fullTitle = `${title} | ${brand}`;
// Length cap: if >60 chars, drop the brand
const safeTitle = fullTitle.length <= 60 ? fullTitle : title;
---
<title>{safeTitle}</title>
Step 5: Block duplicates at build time
// scripts/check-titles.mjs
import fg from "fast-glob";
import fs from "node:fs";
const seen = new Map();
const issues = [];
for (const f of fg.sync("dist/**/*.html")) {
const html = fs.readFileSync(f, "utf8");
const title = html.match(/<title>([^<]+)<\/title>/)?.[1]?.trim();
if (!title) issues.push(`MISSING: ${f}`);
else if (title.length > 60) issues.push(`TOO LONG (${title.length}): ${f}`);
else if (seen.has(title)) issues.push(`DUPLICATE: ${f} == ${seen.get(title)}`);
else seen.set(title, f);
}
if (issues.length) { console.error(issues.join("\n")); process.exit(1); }
Step 6: Wait 14 days, check CTR
Search Console → Performance → compare CTR per URL before / after the change. From 1.5% to 3%+ means the fix worked.
Prevention
- Write titles like a human reads, not a robot — they should sound natural out loud
- One clear H1 per page, semantically aligned with the title
- Title template is always
{unique content} | {brand}with unique content first - 60 characters is the hard cap — auto-drop the brand if it overflows
- CI blocks at build time: duplicate / missing / over-length titles fail the build
Related
Tags: #SEO #Google #Search Console #Indexing