The following code snippet replaces your current 404 page with a custom one. In other words, it tells WordPress to use a specific existing page as the new 404 page.
Add the snippet either to your theme’s functions.php file, or, better yet, use the Code Snippets plugin.
Remember to set the correct page ID in $custom_404_page_id
/*
A custom function that assigns any of your published pages to be the 404 page.
This works with classic themes only.
If you're on a block theme, you can set a custom 404 through the Site Editor.
*/
function kk_custom_404_template($template) {
// Replace with your desired page ID
$custom_404_page_id = 1;
////////////////////////////////////
if (is_404()) {
$page = get_post($custom_404_page_id);
if ($page && $page->post_status == 'publish') {
// Set up global variables
global $wp_query, $post;
$post = $page;
// Set up the main query
$wp_query->posts = array($page);
$wp_query->post = $page;
$wp_query->post_count = 1;
$wp_query->found_posts = 1;
$wp_query->max_num_pages = 1;
$wp_query->is_404 = true; // Keep 404 status
$wp_query->is_page = true; // Treat as page
$wp_query->is_singular = true; // Treat as singular
$wp_query->is_archive = false; // Not an archive
$wp_query->is_home = false; // Not home
// Set up post data
setup_postdata($post);
status_header(404);
nocache_headers();
if (wp_is_block_theme()) {
// Block theme handling - pass through
return ABSPATH . WPINC . '/template-canvas.php';
} else {
// Classic theme handling
$new_template = get_page_template_slug($custom_404_page_id);
if ($new_template) {
return get_template_directory() . '/' . $new_template;
} else {
return get_template_directory() . '/page.php';
}
}
}
}
return $template;
}
add_filter('template_include', 'kk_custom_404_template', 99);