Canonical tags and duplicate content on templated pages
There is no duplicate content penalty. What exists is more mundane and often more expensive: Google picks one page from a group of similar ones, and it is not always the one you would have picked.
How clustering works
Three stages. Similarity detection across crawled pages, grouping into a cluster, then election of a representative URL for that cluster — the others are kept but not shown.
The rel="canonical" tag is a strong signal in that election, but only one among several: internal links, sitemap membership, redirects, URL structure, hreflang. When those signals contradict each other, the tag loses its effect.
"Alternate page with proper canonical tag" means clustering happened as instructed. "Duplicate, Google chose different canonical than user" means it happened against your instruction.
Where canonicals belong
| Situation | Action |
|---|---|
| Unique standalone page | Self-referencing canonical |
| Sort or tracking parameters | Canonical to the clean URL |
| Paginated hub | Self-referencing on every page, never to page 1 |
| Language variants | Self-referencing canonical plus reciprocal hreflang |
| Two genuinely identical pages | Merge and 301 — not a canonical |
Pagination is the row most often misapplied. Canonicalising page three to page one makes the items listed on page three unreachable, producing exactly the orphans described in internal linking at scale.
Why a canonical gets ignored
- Contradicted by internal links. Every link points to A, but A canonicalises to B.
- Canonical chains. A to B, B to C: the chain is liable to break.
- Canonical to a noindex page. Contradictory by construction.
- Pages too dissimilar. If A and B are not alike enough, Google refuses to cluster them — a canonical is not a redirect.
- Relative or malformed URL. Canonicals must be absolute, with protocol and host.
Merge or canonicalise: three measurements
text_similarity = shared_ngrams / total_ngrams
serp_overlap = |top10(A) ∩ top10(B)| / 10
query_overlap = shared_gsc_queries(A,B) / total_queries(A)
| Measure | Threshold | Decision |
|---|---|---|
| Text similarity | Above 85% | Merge into one page |
| SERP overlap | Above 60% | Merge — same intent |
| Query overlap | Above 50% | Cannibalisation in progress; pick a winner |
SERP overlap is the most reliable of the three: two texts can differ substantially while answering the same intent. Catching this before generation is covered in keyword modifiers and clustering. When a merge removes a URL for good, notify the engines that consume IndexNow so the deletion clears faster.
Prevent rather than repair
- One mandatory non-templated block per page, fed by entity-specific data.
- A similarity check at generation time that blocks publication past the threshold.
- Database-enforced title uniqueness, per title templates at scale.
- One canonical URL per piece of content, decided when the URL scheme is designed.
Fixing duplication after publication always costs more: merging, redirecting, updating internal links, then waiting weeks for the change to register.
Frequently asked questions
Is duplicate content penalised?
No. Google simply clusters similar pages and shows one. The real cost is diluted signals and wasted crawl budget, not a sanction.
Does every page need a canonical tag?
A self-referencing canonical is a sensible default. It neutralises accidental variants created by URL parameters and tracking links.
Canonical or 301 redirect?
Redirect when only one URL should survive and remain reachable. Canonical when both must stay reachable but only one should be indexed.