My challenge today is building a 404 page for a large blog about retirement investments. This site has over 500 posts in 13 major categories, so it’s a safe bet that there is something on the site that is relevant to most searches.
We know that GeneratePress can do Related Posts, and we know that it can build custom 404 pages… but can we create a custom 404 page that suggests related content based on the missing page’s URL, like a Search Results page (and without additional plugins just for this one feature)? I think so.
Required:
- GeneratePress Premium
- GenerateBlocks Pro
- Code Snippets plugin (or an alternative that inserts code to functions.php)
In a nutshell, the goal for this page is:
- A friendly Not Found message that reduces instant window-closures.
- Get the page URL that was entered by the visitor, or clicked on (if it’s a broken link).
- Use that URL name to search for related content.
- Display the related content in a grid or list so the visitor has relevant options that keep them on the site. To me, this is different, and better, than a generic “Recent Posts” section.
1. Create the 404 Page Template
Appearance > Elements: Add New Element – Block Type.
In the Element sidebar, set Element Type to Content Template.
Under Display Rules, set Location to 404 Template.
Add a container block with the Not Found message and the suggested next step.
This is what this particular one looks like.
2. Set Up the List or Grid Where Search Results Will Appear
Add a GB Query Loop and click Add Parameter. Choose “Search” and then enter “search_placeholder” in the (keyword) Search box.
Next, select the Grid Block under/inside the Query Loop. In the sidebar’s Advanced section, add an Additional CSS Class*1. For this example, we’re using “related-404-grid”. (CSS classes and IDs cannot begin with numeric digits.)
3. Modify the Query Loop to Display Results Based on the Visitor’s Search
Now comes the semi-complicated part. We want to automatically modify the Query Loop’s search based on the 404’s missing page URL. This requires code.
Back in the WP dashboard, Code Snippets > Add New Snippet. Here’s the code (inspired by a snippet originally found here):
add_filter( 'generateblocks_query_loop_args', function( $query_args, $attributes ) {
global $wp;
// Find the query loop grid
if ( ! empty( $attributes['className'] ) && strpos( $attributes['className'], '404-related-grid' ) !== false ) {
// Get the page URL that was requested.
$missing_page = add_query_arg( array(), $wp->request );
// Break requested URL into individual words based on hyphenation.
$missing_page_keywords = str_replace( "-", "+", $missing_page );
$query_args = array(
'post_type' => array( 'page', 'post' ), // searching both pages and posts
'post_status' => 'public', // only want results that are published
's' => $missing_page_keywords,
'compare' => 'LIKE',
);
}
return $query_args;
}, 10, 2 );
Note where my custom class name ‘404-related-grid’ appeared; replace that with the CSS class you chose in Step 2 above.*1
That’s it! Surprisingly easy, and hopefully keeps people on your site longer when they didn’t find what they came for.