CanonicalTag.com logoCanonicalTag.comThe canonical tag & URL canonicalization
CMS PlatformCMS & Website Platforms

Canonical Tags in WordPress

WordPress core ships a canonical tag on every post and page — but archives, search results, and your homepage are on their own.

Does WordPress add canonical tags automatically?

Yes, and it has for a long time. WordPress core has emitted a self-referencing rel=canonical tag on singular views since version 2.9.0, through a function called rel_canonical() that's hooked to the wp_head action (add_action('wp_head', 'rel_canonical')). If you're running stock WordPress with no SEO plugin and you view source on a single post, you will see a canonical link tag pointing back at that post's own URL. You didn't configure it; core put it there.

There's a nuance worth clearing up, because it trips people up in forums and comment threads: you'll often see WordPress's canonical support dated to version 4.6. That's not when auto-canonicals started — that credit goes to 2.9.0. What WordPress 4.6.0 actually introduced was a helper function, wp_get_canonical_url(), and a filter, get_canonical_url, that let developers read and override the canonical URL programmatically. In other words, 4.6 didn't create the feature; it gave developers a clean, documented way to hook into it. Treat any claim that WordPress added canonical tags in version 4.6 as imprecise at best.

The distinction matters if you're trying to date a canonical-related bug fix or feature to a specific release, or if you're reading older documentation that predates the 4.6 helper functions. A site running any reasonably current version of WordPress core has had self-referencing canonicals on singular content for years; what changed in 4.6 was how easy it became for developers to interact with that existing behavior in code, not whether the behavior existed.

What WordPress core covers — and what it skips

The self-referencing canonical is gated by a single conditional check inside core: if (!is_singular()) return;. That one line determines everything. It means the automatic canonical tag appears only on singular content types — single posts, static pages, media attachment pages, and custom post types. Anything that isn't a singular view gets nothing from core.

Concretely, that means WordPress core does not emit a canonical tag on: the front page (when it's set to show latest posts), the blog index, category archives, tag archives, other taxonomy archives, author archives, date archives, internal search results pages, or the 404 page. If you're auditing a plugin-free WordPress install and you find no canonical tag on a category page, that's not a bug — it's core behaving exactly as designed. This is one of the most consequential gaps in WordPress's out-of-the-box SEO handling, because archive pages, paginated listings, and search results are exactly the kind of near-duplicate content that canonical tags exist to resolve.

There's also no admin screen for any of this. WordPress core gives you no settings page, no metabox, no field to view or edit the canonical URL it's generating. The only way to confirm what core is doing is to inspect the rendered <head> of a live page.

How to add or override a canonical without a plugin

If you're not running an SEO plugin and want to override or extend the canonical WordPress generates, the 4.6+ get_canonical_url filter is the supported entry point. A common pattern is to let a custom field override the default when one is set, and otherwise fall back to WordPress's own computed URL:

add_filter('get_canonical_url', function($url, $post) {
  $o = get_post_meta($post->ID, 'canonical_url', true);
  return empty($o) ? $url : $o;
}, 10, 2);

This snippet checks a post meta field named canonical_url; if an editor has filled it in, that value wins, otherwise WordPress's default self-referencing URL is used unchanged.

There's an important limitation to understand before you build on this: get_canonical_url only fires from inside wp_get_canonical_url(), and that function is itself gated by the same singular-only check described above. You cannot use this filter to add canonical tags to archive pages, the homepage, or search results — it simply never runs on those templates. If you want canonical tags on non-singular views without a plugin, you have to hook wp_head directly and echo your own <link rel="canonical"> markup based on the current query.

If you're replacing core's output entirely — for example, because a theme or custom function now handles canonicals — remove the default first with remove_action('wp_head', 'rel_canonical'). Skipping this step is how sites end up with two canonical tags on the same page.

Adding canonicals with an SEO plugin

This is why nearly every serious WordPress SEO setup runs a plugin: Yoast SEO and Rank Math both generate self-referencing canonical tags across page types that core leaves untouched, including archives, the homepage, and paginated views, closing the gap described above. They don't just add an extra tag alongside core's — they take over the job entirely. Yoast, for instance, removes core's rel_canonical hook and prints its own, so a properly configured Yoast install outputs exactly one canonical tag per page, not two.

That removal step matters if you're troubleshooting a duplicate-canonical issue. If you see two rel=canonical tags on one page, the most common cause is a plugin (or theme code) failing to remove core's default before adding its own — the same remove_action('wp_head', 'rel_canonical') pattern discussed above, just executed by the plugin instead of by you. Understanding that WordPress core's canonical logic still exists underneath any SEO plugin is useful diagnostic knowledge, even if you never touch the code directly.

Rank Math follows the same general pattern on posts, pages, and custom post types: by default it uses the current post or page URL as the canonical, respecting whatever permalink structure the site has configured. Its override field lives in the Rank Math meta box's Advanced tab; if that tab isn't visible, Advanced Mode needs to be enabled first under Rank Math → Dashboard. Leaving the field blank keeps the self-referencing default, the same convention Yoast uses.

Common WordPress canonical mistakes

Three mistakes show up repeatedly on WordPress sites, and all three trace back to misunderstanding what core actually does.

  • Assuming archives already have a canonical tag. Because single posts and pages get one automatically, it's easy to assume category, tag, and date archives do too. They don't, unless an SEO plugin is active. Auditing a plugin-free site without checking this leads people to wrongly conclude a duplicate-content problem is already handled.
  • Hardcoding a canonical tag in header.php on top of core's output. Developers sometimes add a static or template-based <link rel="canonical"> directly in the theme's header file without removing core's automatic tag first. The result is two canonical tags on singular pages — one from core, one from the theme — which search engines have to interpret as conflicting signals rather than a clear hint.
  • Confusing the canonical redirect system with the canonical tag. WordPress core has a separate mechanism, redirect_canonical(), that issues 301 redirects to clean up things like incorrect trailing slashes or malformed URLs. It shares the word canonical in its name, but it is not the rel=canonical tag and does not control it. Treating the two as the same system leads to wasted debugging time when one is working correctly and the other isn't.

Frequently Asked Questions

Does plain WordPress, with no SEO plugin, add canonical tags to every page?

No. WordPress core only outputs a self-referencing canonical tag on singular content — single posts, pages, attachments, and custom post types. Archives, the homepage set to show posts, search results, and the 404 page get no canonical tag from core at all.

Was canonical tag support added to WordPress in version 4.6?

Not the feature itself. Core has emitted canonical tags on singular content since WordPress 2.9.0. Version 4.6.0 added the wp_get_canonical_url() helper function and the get_canonical_url filter, which gave developers a documented way to read and override the canonical WordPress was already generating.

Can I use the get_canonical_url filter to add a canonical to a category archive?

No. That filter only runs inside wp_get_canonical_url(), which is itself restricted to singular views. It never fires on archive, search, or homepage templates. To add canonical tags there without a plugin, you need to hook wp_head directly and output the tag yourself based on the current query.

Why does my WordPress page have two canonical tags?

This almost always happens when a theme or custom function adds its own <link rel="canonical"> without first removing core's default output via remove_action('wp_head', 'rel_canonical'). The same issue can occur if an SEO plugin and a theme are both trying to manage canonicals independently.

Is the WordPress canonical redirect the same thing as the rel=canonical tag?

No, and confusing the two is a common mistake. WordPress's redirect_canonical() function issues 301 redirects to normalize malformed URLs (like fixing a missing trailing slash). The rel=canonical tag is a separate, non-redirecting HTML hint in the page's head. They share a name but do different jobs.