WordPress Canonical Redirect: How It Works, How to Disable It

WordPress can serve the same content under several different URLs. When that happens, search engines may treat each variant as a separate page, which splits ranking signals and can mark the content as duplicate.

Canonical tags and redirects serve different roles. A canonical tag is a signal to search engines indicating which URL should be treated as the primary one for indexing. A canonical redirect enforces this by sending alternative URLs to the preferred one.

WordPress supports both, but default implementation does not cover all cases. This article explains limitations, debugging steps, and how to disable them when needed.

Canonical redirect graphic

Key Takeaways

  1. Canonical redirects in WordPress are implemented via the redirect_canonical() function.
  2. If the canonical redirect does not work as intended, it can be deactivated using a custom code snippet or additional plugin.
  3. By default, WordPress adds canonical meta tags for single posts and pages, but not for archive pages like categories, tags, custom taxonomies, and authors.

Why WordPress Serves The Same Content Under Many URLs?

WordPress uses a system of rewrite rules (based on regular expressions) to determine what content a visitor is trying to access. When WordPress processes a URL, it only considers the "slug" (the specific name of the post or term in the URL) and searches its database for a match.

This helps when a visitor enters a malformed or incomplete URL, or when tracking parameters or referral tags are appended to the original address, for example:

https://example.com/sample-page/
https://example.com/sample-page?ref=instagram
https://www.example.com/sample-page/1/

The problem is that this approach relies on loose matching. If WordPress finds a matching slug, it will try to load the page even when the URL differs from the preferred format.

For visitors, this usually makes no noticeable difference. Search engines, however, need a clear signal about which URL version should be treated as the primary one.

Without a canonical URL, search engines may interpret each URL variant as a separate page, which can lead to duplicate content issues and dilute ranking signals across multiple URL variants.

Canonical Redirect

A canonical redirect ensures that every page can be always accessed through a single (canonical) URL. When a page is available under multiple addresses, the canonical redirect automatically sends visitors from any alternative version to the preferred URL address.

This helps prevent duplicate content issues and preserves SEO value ("juice") from backlinks when URLs are updated or changed. It also helps search engines avoid crawling multiple near-identical or outdated URLs, which can waste crawl budget.

There are two main types of redirects, each defined by different HTTP status code:

  1. 301 redirect: used when a page has been permanently moved to a new URL.
  2. 302 redirect: used for temporary changes when the original URL will be restored later.

How Does Canonical Redirect Work in WordPress

Having the same content available at multiple URLs can hurt both usability and SEO. WordPress avoids this by forcing one canonical URL and redirecting the other variants to it, using the "redirect_canonical()" function.

The function hooks into the "template_redirect" action and runs late in the load process, once WordPress knows which content the URL refers to. The target (canonical) URL is passed through a filter, allowing plugins or themes to modify or disable it.

The canonical redirect is enabled by default. WordPress does not provide a dedicated setting field in the admin dashboard to disable it. To disable it, you will need a custom PHP snippet or a separate plugin.

The WordPress.org documentation barely covers this, but alongside the built-in canonical redirect, two additional functions extend it to help prevent 404 errors: redirect_guess_404_permalink() and wp_old_slug_redirect() .

Function Primary Goal How it Works
redirect_canonical Enforces a single canonical URL to prevent "duplicate content" issue. When a page is requested through a non-canonical (alternative) URL variant, the visitor is redirected to the canonical permalink.
redirect_guess_404_permalink Finds the closest matching content when a URL would otherwise return a 404 error. When the requested URL does not match any content, WordPress tries to find a post with a similar slug and redirects the visitor to it instead of returning a 404 "error".
wp_old_slug_redirect WordPress stores previously used slugs and redirects any old URL containing them to the current permalink.

Why WordPress Redirects a Mistyped URL

One of these is the "redirect_guess_404_permalink()" function. Most site owners do not even know this feature exists. The idea behind it is to "correct" the URL address used by the visitor and redirect them to a valid page instead of showing 404 error.

This function is triggered when a user opens a URL that does not exist, for example because of a typo or a broken link. By default, WordPress tries to guess a similar URL and redirects the visitor there.

URL with the typo:
https://example.com/product/shir/cotton/pique-polo

Canonical URL (redirect target):
https://example.com/product/shirts/cotton/pique-polo

Many of my customers reported that WordPress sometimes redirect their visitors to the wrong pages. If you see this happening on your website, you can switch it off using the code snippet provided at the end of this article.

Old Slug Redirect

The other redirect function is "wp_old_slug_redirect()", which prevents "404 Not found" errors by handling outdated URLs and tracking when a native slug has been changed. It works through WordPress storing earlier slugs in the "_wp_old_slug" meta field.

When a visitor tries to access an outdated URL, WordPress checks whether it contains a previously used slug. If a match is found, the visitor is redirected to the current URL instead of seeing an error page.

For example, imagine you created a page titled "Cape Verde", which generated the slug "cape-verde".

Old URL:
https://example.com/africa/cape-verde/

If you later update the title to "Cabo Verde" and change the slug to "cabo-verde", the old slug remains in the database. Anyone visiting the original URL will be redirected to the new address:

Redirect target URL:
https://example.com/africa/cabo-verde/

The feature is useful but limited. Because stored slugs are not displayed anywhere in the admin dashboard, they cannot be easily reviewed or analyzed.

Canonical Tag

How to Find a Page's Canonical URL

WordPress adds canonical meta tags on its own, even if you do not have any extra SEO plugin installed. The built-in rel_canonical() function prints the tag in the ' <head> ' section of every single post and page.

The easiest way to find a page's canonical URL is by checking its HTML source code. This is helpful, but the meta tag itself does not promise that Google will always respect it.

When a page exists at several URLs, Google might pick a different version to show in search results. Therefore, using a canonical redirect is an additional precaution to make sure the preferred URL is used.

Meta tag in HTML source

Limitations of the rel_canonical() Function

The catch is that rel_canonical() function works only for single posts and pages. Archive pages, such as categories, tags, custom taxonomies and authors are generated without a canonical tag.

In 2011, Nathan Rice suggested adding support for archive pages to this function. Although his proposal was discussed, it has never been implemented, and the Trac ticket is still open.

There are two ways to fix this. You can install an additional SEO plugin, or you can add the meta tags to archive pages with a short code snippet.

Adding Canonical Tags Without a Plugin

Sometimes, plugins can result in conflicting or duplicated canonical tags, particularly with custom post types, archives, or complex layouts. This code snippet gives you full control, letting you adjust the canonical logic exactly how you need.

This snippet below replaces the built-in function and adds the canonical tag for all post types, taxonomies, and archives:

  1. Front page
  2. Blog index page
  3. Single posts, pages, and custom post types
  4. Paginated content
  5. Category and taxonomy archives
  6. Author archives
  7. Date-based archives (year/month/day)

The Snippet

This is a standard solution designed to work for most WordPress websites and you only need a basic skills to implement it. Keep in mind, that it may not work with every plugin you might have installed.

<?php
/**
* Remove the built-in canonical tag to make sure that is not duplicated
* with the new custom code
*/
remove_action( 'wp_head', 'rel_canonical' );
/**
* Adds a canonical <link> tag to the <head> for various types of pages.
*
* Supports single posts/pages, taxonomies, custom post type archives,
* author archives, date archives, and paginated archives.
*
* @return void
*/
function add_canonical_link() {
	$canonical_url = '';
	// A. Canonical URL for the front page.
	if ( is_front_page() ) {
		$canonical_url = home_url( '/' );
	} // B. Canonical URL for the blog posts page.
	elseif ( is_home() ) {
		$page_id = get_option( 'page_for_posts' );
		$canonical_url = $page_id ? get_permalink( $page_id ) : get_home_url();
	} // C. Canonical URL for single posts/pages/CPT items
	else if ( is_singular() ) {
		$canonical_url = wp_get_canonical_url();
	} // D. Canonical URL for archive pages
	elseif ( is_category() || is_tax() || is_post_type_archive() || is_author() || is_date() ) {
		$canonical_url = get_archive_link( get_queried_object() );
	}
	if ( ! empty( $canonical_url ) ) {
		echo '<link rel="canonical" href="' . esc_url( $canonical_url ) . '" />' . PHP_EOL;
	}
}
add_action( 'wp_head', 'add_canonical_link' );
/**
* Returns the archive link for a taxonomy term or post type archive,
* including pagination when applicable.
*
* @param object $archive The queried object.
*
* @return string
*/
function get_archive_link( $archive ) {
	$link = '';
	if ( is_category() || is_tax() ) {
		$link = get_term_link( $archive );
	} elseif ( is_post_type_archive() ) {
		$link = get_post_type_archive_link( $archive->name );
	} elseif ( is_author() ) {
		$link = get_author_posts_url( $archive->ID );
	} elseif ( is_date() ) {
		$link = get_date_archive_link();
	}
	if ( empty( $link ) ) {
		return '';
	}
	$paged = max( 1, get_query_var( 'paged' ) );
	if ( $paged > 1 ) {
		$link = get_pagenum_link( $paged );
	}
	return $link;
}
/**
* Returns the canonical URL for a date archive (year, month, or day).
*
* @return string Canonical URL for the date archive.
*/
function get_date_archive_link() {
	$year = absint( get_query_var( 'year' ) );
	$month = absint( get_query_var( 'monthnum' ) );
	$day = absint( get_query_var( 'day' ) );
	if ( $year && $month && $day ) {
		return get_day_link( $year, $month, $day );
	}
	if ( $year && $month ) {
		return get_month_link( $year, $month );
	}
	if ( $year ) {
		return get_year_link( $year );
	}
	return '';
}

Troubleshooting

Fixing Canonical Redirect Loops

Canonical redirects help prevent duplicate content by forwarding users to a preferred URL, but only when configured correctly. They can break when plugin conflicts or server-level rules override WordPress's PHP-based redirect functions, causing redirect loops.

To find the root of the problem, start by examining the HTTP response headers. When a redirect is triggered via the native wp_redirect() function, it should include an "X-Redirect-By" HTTP header that can help determine where the redirect originates.

HTTP response with "X-Redirect-By" headerAnother method is to deactivate plugins and the theme one by one to isolate the problem. If none of these steps help, see this article for more tips on debugging WordPress redirects.

How to Disable Canonical Redirect in WordPress

Disabling Canonical Redirect With Code

The native canonical redirect works reliably in most cases, but it may occasionally conflict with custom code or plugins. Use the code snippet below to turn canonical redirect off completely, or to disable it only for specific modules.

# Disable canonical redirect completely
remove_action( 'template_redirect', 'redirect_canonical' );
# Disable "old slug" redirection
remove_action( 'template_redirect', 'wp_old_slug_redirect' );
# Disable "guess 404 permalink" redirection
add_filter( 'do_redirect_guess_404_permalink', '__return_false' );

 

Disabling Canonical Redirect in Permalink Manager

If you use the Permalink Manager plugin, you can disable the canonical redirect in the plugin settings without adding any code snippet. This option is also available in the free version (Permalink Manager Lite).

Canonical redirect settings

Last updated by Maciej Bis on: June 2, 2026.


Maciej BisFounder of Permalink Manager & WordPress Developer

The developer behind Permalink Manager, a plugin for managing permalinks, has been working with WordPress, creating custom plugins and themes, for more than a decade.

Leave a Reply

Your email address will not be published. Required fields are marked *