We had an unusual situation where we deleted a page and wanted to serve a 404 error page in its place.
Instead, anyone who went to that URL was redirected to another page on the site.
That hadn't happened with any other URLs. Then it happened with another page we deleted.
There were no redirect plugins in place and no redirects in the .htaccess file.
On further investigation, WordPress was guessing that if we typed in a partial match for a longer URL, we must have meant that longer URL.
That's when I came across canonical redirects.
How to stop WordPress partial match redirection: on WordPress 5.5 and above, add a filter to 'do_redirect_guess_404_permalink' that returns false. For earlier versions, add a filter to 'redirect_canonical' that returns false if is_404() is true or returns the URL.
WordPress 5.5+ Solution
Since WordPress 5.5.0, if you want to stop WordPress guessing the permalink and return a 404 error, use this code:
add_filter( 'do_redirect_guess_404_permalink', 'stop_redirect_guess');
function stop_redirect_guess() {
return false;
}
Solution For Older WordPress Versions
On older versions of WordPress, we need to connect earlier in the sequence and check if we're on a 404 page.
This code still works in newer versions of WordPress, so if you need something that covers before and after an upgrade, use this code.
Here's how it looks in code:
add_filter( 'redirect_canonical', 'stop_redirect_guess' );
function stop_redirect_guess( $url ) {
if ( is_404() ) {
return false;
}
return $url;
}
or if you prefer something more compact, you could use:
add_filter( 'redirect_canonical', 'stop_redirect_guess' );
function stop_redirect_guess( $url ) {
return is_404() ? false : $url;
}
That's the same functionality as the previous, just as a ternary operator.
Strict Match Guessing
In WordPress 5.5+ you can also control whether the guess is strict or not using this code:
add_filter( 'strict_redirect_guess_404_permalink', 'strict_redirect_guessing');
function strict_redirect_guessing() {
return true;
}
This to be useful in is where you have a folder structure and you only want to redirect when the full slug is present.
For example, with strict guessing turned to true, domain.com/hello will no longer redirect to domain.com/2020/09/hello-world/ but domain.com/hello-world will redirect.
If you have strict guessing turned to false (or delete your code), domain.com/hello will redirect to domain.com/2020/09/hello-world/.
The same applies to contractions. With strict guessing turned off, domain.com/find/sample will redirect to domain.com/sample-page/ but it will not redirect if you turn strict guessing off.
The way the strict guessing works is the SQL uses post_name LIKE [slug]% as default or post_name = [slug] for strict matching.
Excellent, you have helped a lot
Excellent, I have so many such half or partial urls (around 300) and I did not know the remedy. Just going to apply the code and check out. Have been dealing with this problem for some time now. Somehow stumbled on your article today. Thanks a lot for publishing this!