How to force a 404 on WordPress

I need to force a 404 on some posts based on conditions. I managed to do it ( although I don’t know if I did it the right way) and I’m a getting my 404.php template to load as expected.

My code:

function rr_404_my_event() {
  global $post;
  if ( is_singular( 'event' ) && !rr_event_should_be_available( $post->ID ) ) {
    include( get_query_template( '404' ) );
    exit; # so that the normal page isn't loaded after the 404 page
  }
}

add_action( 'template_redirect', 'rr_404_my_event', 1 );

Code 2 from this related question – same problem:

function rr_404_my_event() {
  global $post;
  if ( is_singular( 'event' ) && !rr_event_should_be_available( $post->ID ) ) {
    global $wp_query;
    $wp_query->set_404();
  }
}

add_action( 'wp', 'rr_404_my_event' );

My Issue:

Although it looks good, I get a status 200 OK if I check the network tab. Since it’s a status 200, I am afraid that search engines might index those pages too.

Expected Behaviour:

I want a status 404 Not Found to be sent.

7

You could try the WordPress function status_header() to add the HTTP/1.1 404 Not Found header;

So your Code 2 example would be:

function rr_404_my_event() {
  global $post;
  if ( is_singular( 'event' ) && !rr_event_should_be_available( $post->ID ) ) {
    global $wp_query;
    $wp_query->set_404();
    status_header(404);
  }
}
add_action( 'wp', 'rr_404_my_event' );

This function is for example used in this part:

function handle_404() {
    ...cut...
    // Guess it's time to 404.
    $wp_query->set_404();
    status_header( 404 );
    nocache_headers();
    ...cut...
}

from the wp class in /wp-includes/class-wp.php.

So try using this modified Code 2 example in addition to your template_include code.

Leave a Comment