WordPress: How to disable WordPress' canonical redirect to the nearest matching URL and force a 404 page?

When working with WordPress, there may be times when you want to change the default behaviour and force certain pages to return a 404 error instead of being redirected. This can be useful in situations where you want to hide certain URLs or provide a custom error page instead of the default redirect.

In this blog post, we will look at a custom PHP code snippet that allows you to stop WordPress redirects and instead force certain pages to return a 404 error page.

Background
When you visit a page on a WordPress website, WordPress processes the request and tries to find the most appropriate page to display. This can result in redirects where WordPress tries to match the URL with an existing page.

But what if you want to change this behaviour and prevent WordPress from redirecting certain URLs? This is where the custom code example comes in.

Example: example.com/cars/make/model/car.

Above is a parent/child relationship defined with the car brand and car model, with hierarchy for a given post type. In cases where you enter a car model that doesn't exist, WordPress' default redirect behaviour will send the traffic to the parent page. However, I want to define a 404 error page.

**Example:**

example.com/cars/audi/80.

This is not a valid path. I therefore expect to see a 404 error page, which is the case where this function is relevant.

Code example
Here's the PHP snippet:


add_filter('redirect_canonical', 'RedirctStop');
public function RedirctStop( $redirect_url ) {
    global $wp;
    $url = home_url( $wp->request );
    $matchThis = (strpos($url, 'elbilmatch'));
    if (!$matchThis) return $redirect_url;
    if( $redirect_url !== $url) {
        global $wp_query;
        $wp_query->set_404();
        status_header( 404 );
        nocache_headers();
    }
}

How it works
The code first checks if the URL contains the string 'electric car match'. If it doesn't, the function returns and lets WordPress perform the redirect as normal.

If the URL contains 'electric car match', $redirect_url is compared to the current URL. If they are not the same, WordPress will be set to display a 404 page instead of doing a redirect.

Here's the step-by-step:

public function RedirctStop( $redirect_url ) {: Here you define a public function called RedirctStop, which receives a $redirect_url as a parameter. This function will be called when WordPress attempts to make a redirect.

global $wp;: Here you globalise the variable $wp, which contains information about the current WordPress request.

$url = home_url( $wp->request );: You create a variable $url by using the home_url() function together with $wp->request. This will give you the current requested URL.

$matchThis = (strpos($url, 'electriccarmatch'));: You use the strpos() function to check if the string 'electriccarmatch' exists in $url. If it exists, you assign true to $matchThis, otherwise you assign false.

if (!$matchThis) return $redirect_url;: Here you check if $matchThis is false (i.e. 'electric car match' does not exist in the URL). If this is the case, simply return $redirect_url, which means no changes will be made and WordPress will continue with the redirect as normal.

if( $redirect_url !== $url) {: This is a conditional statement that checks if $redirect_url is not the same as $url, suggesting that WordPress is trying to redirect the user.

global $wp_query;: Here you globalise $wp_query, which is used to manipulate the WordPress query.

$wp_query->set_404();: You're telling WordPress to set a 404 status code, which means the page doesn't exist.

status_header( 404 );:: You set the HTTP status code to 404 so that the server and browser understand that the page does not exist.

nocache_headers();: This helps prevent caching of the 404 page.

Implementation
To implement this code example, add it to your WordPress installation's theme functions or use it as part of a custom plugin. The function is started using add_filter with redirect_canonical. This adds the RedirctStop function as a filter on redirect_canonical. Now the function will be executed when WordPress attempts to make a redirect.