20

I recently noticed that Wordpress tries to auto-complete a URL when it's not submitted in its entirety. E.g. I have a post URL that looks like this:

http://www.mysite.com/some-post-title

If I browse to the following URL:

http://www.mysite.com/some-post-ti

I can see that the URL is submitted to Wordpress but that Wordpress is doing a 301 redirect to http://www.mysite.com/some-post-title.

How can I disable this behavior?

1
  • A tested solution that does not disable the whole canonical URL system but only disables the autocomplete "guessing" part is outlined here
    – Hauke P.
    May 20, 2014 at 14:56

4 Answers 4

28

I believe that is the redirect_canonical function hooked to template_redirect. You should be able to disable it with:

remove_filter('template_redirect', 'redirect_canonical'); 

But you should really think about whether you want to do that as it is fairly complicated and performs some important SEO functions:

Redirects incoming links to the proper URL based on the site url.

Search engines consider www.somedomain.com and somedomain.com to be two different URLs when they both go to the same location. This SEO enhancement prevents penalty for duplicate content by redirecting all incoming links to one or the other.

Prevents redirection for feeds, trackbacks, searches, comment popup, and admin URLs. Does not redirect on non-pretty-permalink-supporting IIS 7, page/post previews, WP admin, Trackbacks, robots.txt, searches, or on POST requests.

Will also attempt to find the correct link when a user enters a URL that does not exist based on exact WordPress query. Will instead try to parse the URL or query in an attempt to figure the correct page to go to.

http://core.trac.wordpress.org/browser/tags/3.5.1/wp-includes/canonical.php#L13

The following might kill the autocompletion without messing with the SEO component, but I can't promise that. The code is barely tested as I have never wished to disable this. I'd really have to study redirect_canonical to be sure of anything.

function kill_404_redirect_wpse_92103() {
  if (is_404()) {
   add_action('redirect_canonical','__return_false');
  }
}
add_action('template_redirect','kill_404_redirect_wpse_92103',1);
3
  • I added this code snippet to the end of my /wp-includes/canonical.php file and the redirects are still happening. Am I doing something wrong? Anyone else unable to disable this behaviour? Jun 4, 2019 at 16:34
  • 1
    @user1380540 you don't edit core files. this would go to a theme functions.php or to a plugin. Jul 16, 2020 at 18:45
  • another reason I have a love / hate relationship with wordpress
    – JJS
    Jul 21 at 15:25
5

This seems terribly irresponsible, to have this "guessing" occur automatically. I would be much more open to it if there were some means of defining which was the correct page to go to.

I have numerous pages that are built as a sequence, and this auto-guessing is incorrectly choosing to respond with pages that are (randomly?) somewhere in the sequence, as opposed to the starting page.

UPDATE: This is known behavior, and is being considered here: https://core.trac.wordpress.org/ticket/16557

2

As a follow up to FitPM's answer - a plugin has been created that disables the auto-guessing behavior.

It works fine for me on Wordpress 4.8 as of August 2, 2017. The plugin is here: https://wordpress.org/plugins/disable-url-autocorrect-guessing/

1

One note: If one disables redirect_canonical (e.g. with remove_action('template_redirect', 'redirect_canonical');), random links like https://tld.com/some-random-string/blogpost also work (the content of https://tld.com/real-category-slug/blogpost is shown).

If you want to prevent that and return 404 on those random urls, use something like

add_filter( 'redirect_canonical', function( $redirect_url ) {
    $url = 'http'.((isset($_SERVER['HTTPS'])&&$_SERVER['HTTPS']!=='off')?'s':'').'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
    if( $redirect_url !== $url ) {
        global $wp_query;
        $wp_query->set_404();
        status_header( 404 );
        nocache_headers();
    }
    return false; 
});
1
  • 1
    you can simplify it by $url = home_url( $_SERVER['REQUEST_URI'] );
    – Saif
    Dec 25, 2021 at 6:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.