Show Any WordPress Page As Your 404-Page

It’s always the problem to deliver a truely individually designed page as your 404-page, which has all the features of a “normal” page of your theme. The more complex the theme the poorer the 404-page looks.

And often you think, why can’t I just simply create a page to my liking and let WordPress deliver this as my 404-page?

I’ve seen quite some really nice premium themes, which tried to do that. Just unfortunately totally wrong! 🙁

But thank goodness that’s easy to fix!

OK, let’s start with how WordPress handles non-existent URLs.

In general all the URLs in WordPress don’t exist physically. Except you left the permalinks-settings (under “Settings” in the backend menu) on “standard”. Not a good idea, really! Ideally you should include the post-name/page-name in the URL.

Whenever there is an URL requested WordPress looks up if there is a post or page connected to that URLs and if so delivers this page or post. Similar with category- and tag-pages.

But if WordPress doesn’t find anything for the requested URL then it calls (if it exists) a special file in your active theme: the 404.php (and sends out the correct HTTP-Header Statuscode “404 Not Found”. That’s the code, which especially for search-engines, or better their bots/crawlers, is a definitive signal that they shouldn’t index the following content, since this URL doesn’t exist (anymore). So far so good. But we want to show the visitor who somehow got to this wrong, non-existent URL – be it that he mistyped the URL, or he clicked on an outdated link that points to an URL that doesn’t exist anymore, or the linking person made a mistake and mistyped the URL – a pretty, the rest of the website matching page which explains her friendly  or maybe with some humor (works usually very well), that this URL doesn’t exist. And exactly that’s what the 404.php is for.

WordPress suggests (and so you can find it hundredfold on the web) to deliver the 404-Page simply with static or dynamic content. I.e something like this:

<?php get_header(); ?>

<h2>404 Not found</h2>


This URL doesn't exist, please use the search function...

<?php get_search_form(); ?>

<h3>The last 3 posts</h3>


<? php get_latest_posts(3); ?>

<?php get_sidebar(); ?>
<?php get_footer(); ?>

But how can I tell WordPress to deliver a simple normal WordPress page as my 404-Page?

Well, as already said, I’ve seen themes, which tried to do that. Like i.e. this:

<?php /* Template Name: 404 Page Not Found */ header("location:" . get_permalink(ot_get_option("ic_404_page")) ); ?>

For the user this worked like a charm. That means the user got exactly this especially created 404-page. But unfortunately the searchengines’ bots and crawlers didn’t receive this important HTTP-Header status “404 Not Found”, but a “302 Found” and got temporarily redirected to this 404-page, which in turn returned a clean “200” HTTP-Header status. That way the searchengines didn’t receive any information that this is actually an URL that doesn’t exist and shouldn’t be indexed. But instead they received the information that the content of this URL is now to be found under another URL, namely this 404-WordPress-page. But that wasn’t what we intended.

The solution is now this: We copy the content of the theme’s page.php into the 404.php. Hmm, so far so good, but the user doesn’t seet the content of our finely crafted 404-page, since we still have to tell WordPress which page’s contennt should be displayed. Since the URL doesn’t exists WordPress can’t find the correct page. Since WordPress is built in such a way that it doesn’t holds the ID of the page to display in an always available variable, but computes the content to display in it’s “magic” loop – at WordPress you will always hear coders talk about “THE LOOP” – we have to find a way to manipulate this loop, or, like in this solution, to replace it.

For this we have to find the loop in the copied php-code from the page.php. That’s usually not very difficult. “THE LOOP” usually looks like this, even though it might look a bit different.

This is the standard look of the loop:


while ( have_posts() ) : the_post();

or like this:


if ( have_posts()) : while ( have_posts() ) : the_post();

but often just like this – especially, if you know, that you just want to show a single post or page:


if ( have_posts()) : the_post();

Well, exactly this code we have to replace now with our own loop. For that we have to create our own loop. And then we’ll elegantly include the ID of the page we want to display in this loop:

$the404loop = new WP_Query('page_id='.ot_get_option("ic_404_page"));

In this example the theme provides the possibility to define a page as the 404-page via the theme-options, and with the theme-own function call

ot_get_option("ic_404_page")

we’ll retrieve the ID of that page.

Now we just have to replace the original-loop with our own, i.e.:

// if ( have_posts()) : the_post();
if($the404loop->have_posts()) : $the404page->the_post();

in the example above we didn’t delete or overwrite the original loop but commented it out. So we’ll always know what’s been here originally.

It might be that the theme is also referring to the ID of the page to display in other locations of the code. I.e. by using the function

the_ID();

In these spots we’ll have to replace it with the ID of our 404-page. Either staticly, if the theme doesn’t offer the opportunity to refer to a normal page as it’s 404-page, or like in the example above by a function call, which retrieves the ID from the options.

Now finally WordPress delivers our page and still sends the searchengines’ bots and crawlers the correct HTTP-Header status code “404 Not Found”.

Dieser Beitrag ist auch verfügbar auf: German

Leave a Comment