
How to Set Up a Custom 404 Error Page in WordPress?
A default 404 page is a dead end that loses visitors. Someone clicked an old link, mistyped a URL, or followed a broken reference from search results, and instead of finding what they wanted they hit a generic "Not Found" message with nothing to do next. A custom 404 page turns that same moment into a chance to keep them on your site: a search box, a link back to your homepage or most popular content, and copy that doesn't read like an error log.
This guide covers every way to build one in WordPress — theme template files for classic themes, the Site Editor for block themes, and page builder or plugin options for a no-code approach — plus how to make sure the page returns the correct HTTP status code, which most tutorials skip and search engines absolutely check.
How WordPress Decides What Counts as a 404
WordPress determines a request is a 404 when nothing in your content (post, page, category, tag, author archive) matches the requested URL. When that happens, it loads a specific template file, in this order of priority:
404.phpin your active theme (or its parent theme, if you're using a child theme)- Falls back to
index.phpif no404.phpexists
Critically, whatever markup renders for a 404 request needs to be served alongside an actual 404 Not Found HTTP status code, not just a page that visually looks like an error. WordPress handles this automatically for real 404 template files via the is_404() conditional and its own header logic, but if you build a fake 404 page as a regular published page, it will return a 200 OK status by default, which search engines interpret as "this is a real, valid page," not an error. Keep that in mind for every approach below.
Method 1: Edit 404.php Directly (Classic Themes)
If your active theme is a classic (PHP-based, non-block) theme, it likely already ships a 404.php file. The safest way to customize it is through a child theme, so your changes survive a theme update.
- Create a child theme if you don't already have one, and copy
404.phpfrom the parent theme into it (or create a new404.phpif the parent theme doesn't have one). - Edit the file to add your custom content. Here's a solid baseline:
<?php
/**
* The template for displaying 404 pages (Not Found)
*/
get_header();
?>
<main id="primary" class="site-main">
<section class="error-404 not-found">
<header class="page-header">
<h1 class="page-title"><?php esc_html_e( 'Oops! That page can\'t be found.', 'your-theme' ); ?></h1>
</header>
<div class="page-content">
<p><?php esc_html_e( 'It looks like nothing was found at this location. Try one of the links below, or use search.', 'your-theme' ); ?></p>
<?php get_search_form(); ?>
<h2><?php esc_html_e( 'Popular Posts', 'your-theme' ); ?></h2>
<ul>
<?php
$popular = new WP_Query( [
'posts_per_page' => 5,
'orderby' => 'comment_count',
'ignore_sticky_posts' => true,
] );
while ( $popular->have_posts() ) :
$popular->the_post();
?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endwhile; wp_reset_postdata(); ?>
</ul>
</div>
</section>
</main>
<?php
get_footer();
Because WordPress loads this file specifically when is_404() is true, the correct 404 HTTP status header is already sent before this template runs — you don't need to set it yourself.
Method 2: Use the Site Editor (Block Themes)
If your active theme is a block theme (one that supports Full Site Editing), you can build a 404 template visually without touching PHP:
- Go to Appearance > Editor.
- Click Templates, then find and select the 404 template (WordPress ships one by default; if your theme doesn't list it, click Add New Template and choose "404").
- Edit it with the block editor: add a heading, a paragraph, a Search block, and a Query Loop block pointed at your most popular or most recent posts.
- Click Save.
Because this is a real template assigned to the 404 condition, WordPress still returns the correct 404 status code, exactly as with the PHP approach.
Method 3: Use a Plugin (No Code Required)
If you'd rather not touch templates at all, several plugins let you design a 404 page visually and register it properly:
- 404page — a lightweight, focused plugin that lets you assign any existing page as your 404 page, while still returning the correct 404 HTTP status (it hooks into the template redirect process rather than just displaying page content, which is the detail that makes it safe to use instead of just picking a page manually).
- Page builder plugins like Elementor or SeedProd often include a dedicated 404 template type in their theme builder, which handles the status code correctly by design.
Whatever plugin you choose, confirm it's actually returning a 404 status (see the testing section below) rather than dressing up a normal 200 page to look like one.
What to Actually Put on a Good 404 Page
A 404 page that helps rather than frustrates typically includes:
- A clear, human message — "Page not found" is fine; overly cute copy can work but shouldn't obscure what happened.
- A working search box —
get_search_form()in a classic theme, or a Search block in a block theme. - A link back to the homepage, and ideally to your main navigation or a sitemap page.
- A short list of popular or recent posts, as shown in the code example above, so there's always somewhere useful to click next.
- No broken assets or images — the last thing a 404 page needs is its own broken image reference.
Avoid using a full-page redirect to your homepage instead of a real 404 page. It might feel user-friendly, but it also erases the fact that a link was broken, which means you never find out about it and search engines can end up indexing your homepage under the broken URL instead of correctly dropping it.
Tracking 404 Hits with Analytics
Once your custom 404 page is live, it's worth knowing exactly which broken URLs people are landing on, rather than treating the page as a one-and-done fix. If you're using Google Analytics (see how to add Google Analytics to your WordPress website if you haven't set it up yet), you can send a custom event specifically from the 404 template so those hits are easy to filter separately from normal pageviews:
add_action( 'wp_footer', function () {
if ( ! is_404() ) {
return;
}
?>
<script>
if ( typeof gtag === 'function' ) {
gtag( 'event', 'page_not_found', {
'page_location': window.location.href,
'page_referrer': document.referrer
} );
}
</script>
<?php
} );
This fires only on actual 404 requests (thanks to the is_404() check), and captures both the broken URL and where the visitor came from, which is often more useful than the URL alone since it tells you whether the broken link lives on your own site or somewhere external.
You can build a simple report in Google Analytics filtering for the page_not_found event to see your most-hit broken URLs over time, which turns your 404 page from a dead end into an ongoing list of things to fix or redirect.
Redirecting Common 404 Patterns Instead of Just Displaying Them
Some 404s are worth fixing at the source rather than just handling gracefully. If you renamed a page, moved content to a new URL structure, or migrated from another platform with a different URL scheme, a plugin like Redirection (free, in the official repository) lets you set up 301 redirects from the old path to the new one, and — usefully — logs every 404 hit automatically so you can spot patterns without configuring anything extra.
For a small number of known patterns, you can also handle redirects directly in code. For example, if an old blog used /article/post-name and the new permalink structure uses /blog/post-name, you could redirect programmatically:
add_action( 'template_redirect', function () {
if ( ! is_404() ) {
return;
}
$request_path = trim( parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH ), '/' );
if ( str_starts_with( $request_path, 'article/' ) ) {
$slug = str_replace( 'article/', '', $request_path );
$new_url = home_url( '/blog/' . $slug );
wp_safe_redirect( $new_url, 301 );
exit;
}
} );
This runs on template_redirect, before the 404 template renders, so a matching request never actually shows the 404 page at all — it 301s straight to the correct new URL. Anything that doesn't match the pattern falls through to the normal 404 template.
Testing That Your 404 Page Returns the Correct Status Code
Visually checking the page isn't enough — you need to confirm the actual HTTP response. From a terminal:
curl -I https://example.com/this-page-does-not-exist
Look for HTTP/2 404 (or HTTP/1.1 404 Not Found) in the response headers. If you instead see 200 OK, your "404 page" is actually just a regular page with 404-style content, and it needs to be fixed using one of the methods above rather than a manually created page.
Frequently Asked Questions (FAQ) About Custom 404 Pages in WordPress
Not safely on its own. A regular published page always returns a 200 OK status, even if it visually looks like an error page. Search engines and monitoring tools rely on the actual HTTP status code, not the page's content, to know it's an error page, so use one of the methods above that properly triggers WordPress's 404 handling.
Almost certainly yes — WordPress theme review guidelines require a 404.php template (or block theme equivalent) for themes in the official directory. It may just be using minimal, unstyled default content, which is exactly what this guide helps you improve.
No, a well-built custom 404 page that still returns a proper 404 status code has no negative SEO impact, and can actually help by keeping visitors on your site (lowering bounce rate) instead of leaving immediately. The only SEO risk is one that incorrectly returns a 200 status, which can confuse search engines about which URLs are valid.
Generally no. Blanket redirects hide broken links from you and from search engines, and can create confusing "soft 404" situations. It's better to fix or redirect specific broken URLs individually (via a redirect plugin) once you've identified them, and let a good custom 404 page handle everything else.
Check your hosting error logs, a plugin like Redirection (which logs 404 hits automatically), or Google Search Console's Page Indexing report, which lists URLs Google has crawled and found to return 404s.
Yes, if your theme or a form plugin lets you embed a shortcode or block inside the 404 template, it works the same as any other template. Just make sure it doesn't clutter the page to the point where the primary goal (helping the visitor find real content) gets lost.
The underlying WordPress logic (is_404(), sending the correct status code) is identical either way. The difference is only in how you edit the template — PHP and a code editor for classic themes, the visual Site Editor for block themes.
Not necessarily. Redirect broken URLs that used to point to real content that moved or was renamed, since those are genuinely misdirected visitors. Don't bother redirecting truly random or malicious-looking requests (bots probing for common exploit paths, for instance) — those are better left to return a normal 404.
Set up a custom analytics event fired only on is_404(), as shown above, or install a plugin like Redirection that logs every 404 request automatically along with the referring URL. Either approach gives you a ranked list of what to fix first.
Conclusion
A custom 404 page is a small piece of a site that most visitors, ideally, never see — but for the ones who do, it's the difference between leaving immediately and finding their way back to something useful. Whether you build it as a 404.php template, through the Site Editor, or with a plugin, the one non-negotiable detail is making sure it still returns a real 404 Not Found HTTP status, not just 404-looking content on a page that quietly reports success.
Once the page itself is solid, pair it with occasional log or Search Console checks so you're catching and fixing broken links proactively, rather than only ever seeing them from the visitor's side.


