Here’s a scenario that quietly wrecks rankings: your homepage answers at example.com, www.example.com, the http:// version, and again with a stray ?utm_source=newsletter tacked on the end. Four URLs, one page. To you it’s obviously the same site. To Google it can look like four near-identical pages competing for the same spot, and Google gets to decide which one it keeps.
That decision is called canonicalization, and when you leave it to a search engine to sort out, it doesn’t always pick the version you’d want. The fix is the rel="canonical" tag — a small line in your page’s <head> that points every duplicate back to the one URL that counts.
WordPress handles a surprising amount of this for you out of the box. But it has real blind spots, and the query-string and pagination cases are exactly where a small-business site bleeds ranking signals without anyone noticing. This guide covers what canonical URLs are, what WordPress does automatically, where it stops, and how to take control of the rest.
What a Canonical URL Actually Is
A canonical URL is the address you’ve declared to be the definitive, master version of a page. The rel="canonical" link element is how you declare it. Drop this in the <head> and you’re telling search engines “if you find this content under other URLs, treat this one as the original”:
<link rel="canonical" href="https://example.com/my-page/" />
The goal is consolidation. When several URLs serve the same or very similar content, their ranking signals — links, relevance, engagement — get split across all of them. A canonical tag asks the search engine to pool those signals onto one URL instead of diluting them across five.
It’s a hint, not a command
This is the part people get wrong, so it’s worth stating plainly. Google treats rel="canonical" as a strong signal, not an order it must obey. Google’s own documentation is explicit that it uses canonical tags as one signal among several — redirects, sitemap contents, a preference for HTTPS, and how you link across your own pages — when choosing which URL to index, and it can pick a different canonical than the one you specified. You’re casting a heavily-weighted vote, not flipping a switch.
In practice, if your signals are consistent — you link to one version everywhere, your sitemap lists it, it’s on HTTPS — Google almost always honors your choice. Conflicting signals are what get you overruled.
The self-referencing canonical
Every important page should point a canonical tag at itself. That sounds redundant, but a self-referencing canonical is a best practice for a good reason: it locks in the exact URL you want indexed — right protocol, right host, right trailing slash — even when someone reaches the page through a tracking parameter or a slightly different path. WordPress does this for you on posts and pages, which is a big part of why it handles duplication as well as it does.
Duplicate URLs don’t usually trigger a penalty — the older “duplicate content penalty” myth mostly isn’t a thing. What they do is quietly split your ranking signals and waste crawl budget. Google spends time re-crawling the same content under five addresses instead of finding your new pages, and the version it decides to show in results might not be the one you optimized. Canonical tags are how you keep that decision in your hands.
What WordPress Does Automatically
WordPress core is more capable here than most people realize, and two functions do the heavy lifting.
rel_canonical(): the tag on every post and page
Since WordPress 2.9 (released in 2009), core has included a function called rel_canonical() that hooks into wp_head and prints a self-referencing canonical tag on singular views — individual posts, pages, and custom-post-type entries. Visit any post, view source, and you’ll find the tag already there pointing at that post’s clean permalink. You didn’t add it; core did.
There’s an important limit baked into that behavior. The function only fires on is_singular() views. Your homepage, category and tag archives, author archives, date archives, and search results pages get no core canonical tag at all. Those are exactly the templates where WordPress can generate thin or overlapping content, so the gap matters.
redirect_canonical(): the silent 301s
The second piece is redirect_canonical(), which has been in core since WordPress 2.3. This one doesn’t add a tag — it issues actual redirects. When someone (or a crawler) hits a URL that resolves to a post but isn’t the “correct” permalink, WordPress 301-redirects them to the canonical form. The classic example is the ugly ?p=123 query-string URL getting bounced to the pretty /my-post-title/ permalink. It also fixes a missing or extra trailing slash and corrects some capitalization and pagination mismatches.
So between the two, WordPress covers a lot: pretty permalinks are enforced with real redirects, and every post and page ships a self-referencing canonical. What it doesn’t cover is where you have to step in.
Where WordPress Leaves You Exposed
Core’s automation stops at the edges, and those edges are where duplication actually accumulates on a real site.
Query strings and tracking parameters
Add ?utm_source=facebook or ?fbclid=abc123 to any post URL and you’ve technically created a distinct URL serving identical content. Because WordPress’s core canonical tag is self-referencing to the clean permalink, this is the one case core handles gracefully on singular pages — the canonical still points at the parameter-free URL. The problem is everywhere else: campaign links to your homepage, archive pages, or landing pages built outside the standard post templates can pile up parameterized variants with nothing pointing them home.
www vs. non-www and HTTP vs. HTTPS
These aren’t canonical-tag problems so much as configuration problems, and they’re the ones that bite hardest. If your site answers on both www and the bare domain, or still responds on http://, you’ve got parallel copies of your entire site. The right fix isn’t a canonical tag on each page — it’s a server-level 301 redirect that forces everyone onto one host and HTTPS. Set your WordPress Address and Site Address (in Settings, General) to the exact canonical form, and make sure your host or server config redirects the alternatives. Canonical tags are a backstop here, not the primary tool.
Archives, tags, and pagination
Category and tag archives can overlap heavily — assign one post to three tags and it appears on three archive pages plus the main blog. Paginated archives (/blog/page/2/) are another gray area. None of these get a core canonical tag. For most small sites the pragmatic answer is to let an SEO plugin manage archive canonicals and to be deliberate about which taxonomies you even let Google index. You rarely need every tag archive crawled.
Cross-posted and syndicated content
If you republish an article on Medium, LinkedIn, or a partner’s site, whichever copy Google trusts most can outrank your original. When the platform allows it, set the canonical on the republished copy to point back at your own URL. That’s how you keep the ranking credit on your domain instead of handing it to a platform you don’t own.
Same content, different URL params? → canonical to the clean URL.
www vs non-www / http vs https? → fix with a server 301, not a tag.
Republished on Medium/LinkedIn? → canonical the copy back to your original.
Genuinely different pages? → don’t cross-canonicalize; each self-references.
Setting Canonicals the Right Way
You’ve got three layers to work with, and most sites use all three.
Let core handle your posts and pages
For standard blog posts and pages, you usually don’t need to touch anything. Core’s rel_canonical() already emits a correct self-referencing tag, and redirect_canonical() already forces the pretty permalink. Confirm it’s working by loading a post, viewing source, and searching for rel="canonical". If the URL it points to matches your intended permalink with the right protocol and host, that page is done.
Use an SEO plugin for the archives and the overrides
This is where Yoast SEO, Rank Math, SEOPress, and AIOSEO earn their place. They add canonical tags to the templates core ignores — homepage, archives, taxonomies — and they give you a per-page override field so you can point any specific URL wherever you need. When you deliberately want two similar pages consolidated, that override box is the tool. If you run one of these plugins, be aware it typically replaces core’s canonical output with its own, so you manage everything in one place rather than fighting core.
A related note on your SEO metadata generally: getting titles, descriptions, and structured data consistent across a large site by hand is its own slog. That’s the itch our own amplifi.meta plugin scratches — bulk-generating clean SEO meta with AI — though for canonicals specifically, any of the mainstream SEO plugins will do the job.
Fix host and protocol at the server
The one thing no plugin should be your primary fix for is the www/HTTPS split. Enforce a single host and HTTPS with a 301 redirect at the server or host level, set your Site Address correctly, and update internal links to use the canonical form. Once every internal link, your sitemap, and your redirects all point the same way, canonical tags become the belt to that pair of suspenders.
amplifi.meta and the rest of the amplifi.plugins suite are MIT licensed and free — one install for AI-powered SEO meta, schema, security, translation, and more. The full source is on GitHub.
View on GitHubHow to Check What Google Actually Chose
Setting a canonical is only half the job — you also want to know whether Google accepted it. The tool for this is the URL Inspection feature in Google Search Console. Paste in one of your URLs and it reports two values: the canonical you declared, and the “Google-selected canonical.” When those two match, your signals are consistent and you’re done. When they diverge, Google overruled you, and that’s your cue to investigate.
The usual culprits behind a mismatch are the boring ones: an internal link somewhere still points at the non-canonical version, your sitemap lists the wrong URL, or a leftover redirect contradicts the tag. A mismatch is diagnostic, not fatal — it’s telling you where your signals disagree with each other.
A cleanup we actually ran into
On one WordPress cleanup, a site had migrated from HTTP to HTTPS years earlier but never updated its internal links or its Site Address, so half the internal links still pointed at http:// URLs that 301’d to HTTPS. Every crawl wasted hops following those redirects, and Search Console kept flagging canonical mismatches. Nothing was “broken” in a way a visitor would ever see — but the crawl budget was leaking and the ranking signals were smeared across two protocols. Fixing the Site Address and running a search-and-replace on the internal links cleared it up in an afternoon. Consistency, not cleverness, is what canonicalization rewards.
Common Mistakes to Avoid
A few canonical errors do real damage, and they’re easy to make.
- Pointing every page’s canonical at the homepage. This tells Google your interior pages are duplicates of the homepage and can drop them from the index. Each page should self-reference unless it’s a genuine duplicate.
- Canonicalizing paginated archives to page one. Pages 2, 3, and beyond hold different posts; canonicalizing them all to page one can hide those posts from crawling. Let them self-reference.
- Mixing canonical tags with conflicting
noindexor redirects on the same URL. Contradictory signals confuse crawlers and usually mean Google ignores the lot and decides for itself. - Canonicalizing to a URL that redirects, 404s, or is itself noindexed. Always point at a live, indexable, final destination.
- Emitting two different canonical tags on one page — a common side effect of running an SEO plugin alongside a theme or second plugin that also injects one. Pick one source of truth.
Frequently Asked Questions
Not sure which version of your pages Google is actually indexing? Start with the URL Inspection tool in Search Console, make your canonical, internal links, and sitemap all agree, and let a good SEO stack keep them that way.
Built by amplifi.studio — see also our WordPress 301 redirect guide.