When multiple URLs share the same <title>, you teach search engines that those pages cover the same topic. Google deduplicates the cluster down to one URL and demotes the rest. Internal CTR cannibalizes itself.
This is almost always a template problem, not a per-page content problem. One bad title template can produce thousands of duplicates overnight.
How to detect it
Crawl the site, group URLs by exact title, find any group with more than one member.
# After a crawl that lists "URL,Title"
sort -t, -k2 crawl.csv | awk -F, '{ a[$2]++; b[$2]=b[$2]"\n "$1 } END { for (t in a) if (a[t]>1) print a[t], t, b[t] }' | sort -rn | head
Real signal patterns:
- Templated category pages:
/products/category/widgetsand/products/category/gadgetsboth titled “Products — Acme.” - Paginated archives:
/blog?page=1,?page=2,?page=3all titled “Blog — Acme.” - Default fallback: dozens of pages titled just “Acme” because the CMS field is empty and the template falls back to site name.
- Product variants:
/products/widget?color=redand?color=blueboth titled “Widget — Acme.”
The fix — diagnose the source
For each duplicate group, ask: what template is producing this?
If you find the template, fixing 200 URLs becomes a 5-minute edit. If you fix the 200 URLs individually, the next 200 will still come out duplicated.
Three common templates:
- Category / listing pages — title pattern
{category} — {brand} - Paginated pages — title pattern
{base title} — Page {n} — {brand} - Variant pages — usually shouldn’t have their own URL at all; canonical to the parent.
Templates that produce unique titles
Universal — listing pages
<title>{Category name} — {Brand}</title>
For categories, plug the category name in. For pagination, append the page number to all but page 1.
WordPress (Yoast / Rank Math)
Edit the title template per content type. For categories:
- Yoast → Search Appearance → Taxonomies → Category →
%%term_title%% — %%sitename%% - Rank Math → Titles & Meta → Categories →
%term% — %sitename%
For paginated archives, both plugins prepend “Page N” automatically when the page parameter is present. If yours doesn’t, switch on the option.
Shopify
Collection pages share titles by default if you don’t override them. In Online Store → Collections → individual collection → SEO → Page title, set a unique title per collection. For paginated collections, Shopify’s {{ page_title }} already includes “Page N” when applicable.
For product variants, the canonical fix is to not index variant URLs at all — canonical them to the parent product:
<link rel="canonical" href="{{ product.url }}">
Next.js (App Router)
Generate titles from the URL params:
// app/blog/page/[page]/page.tsx
export async function generateMetadata({
params,
}: {
params: { page: string };
}): Promise<Metadata> {
const page = Number(params.page);
return {
title: page === 1
? `Blog — Acme`
: `Blog — Page ${page} — Acme`,
};
}
For category pages, generate from the category data:
// app/category/[slug]/page.tsx
export async function generateMetadata({
params,
}: {
params: { slug: string };
}): Promise<Metadata> {
const cat = await getCategory(params.slug);
return { title: `${cat.name} — Acme` };
}
Pitfalls
Don’t fix duplicates by noindex-ing the duplicates. That removes pages from the index entirely — fine for low-value pagination, bad for product variants and category pages with real demand. Fix the title first.
Don’t canonical product variants together unless they truly are the same product. A red and a blue version are different SKUs to a buyer; consolidating them via canonical hides the variant. Use unique titles instead.
Don’t ignore the source of duplicates. If your CMS template is producing them, individual page fixes are endless. Fix the template once.
Pagination is the exception. Page 2 of a blog archive sharing topical content with page 1 is expected — vary the title with “Page 2,” keep <link rel="canonical"> self-referential. Google deprecated rel=next/prev in 2019; don’t use it.
Fix at the edge with Serpwise
When duplicate titles come from a template you can’t change quickly — a hosted CMS, a legacy section behind a different stack, a third-party product page builder — fixing the source is slow.
Serpwise can rewrite titles at the edge based on URL patterns and on-page signals: “for every /products/* URL, set <title> to the first <h1> text plus — Acme.” Apply to thousands of URLs in minutes, audit in one dashboard, deprecate as the upstream template catches up.
See pricing or run a free AI visibility audit.