Blog

Smart 404 for WordPress

Save visitors to your WordPress site from unhelpful 404 errors!

When a page cannot be found, Smart 404 will use the current URL to attempt to find a matching page, and redirect to it automatically. Smart 404 also supplies template tags which provide a list of suggestions, for use on a 404.php template page if a matching post can’t be immediately discovered.

Instead of quickly giving up when a visitor reaches a page that doesn’t exist, make an effort to guess what they were after in the first place. This plugin will perform a search of your posts, tags and categories, using keywords from the requested URL. If there’s a match, redirect to that page instead of showing the error. If there’s more than one match, the 404 template can use some template tags to provide a list of suggestions to the visitor.

This plugin is also useful if you have recently changed your permalink structure: With minimal or no adjustment, old permalinks will still work.


My latest project:

The Cartographer banner


Download

Get Smart 404 over at the Smart 404 WordPress Plugin page!

Installation

  1. Unzip the package, and upload smart404 to the /wp-content/plugins/ directory on your WordPress site.
  2. Activate the plugin through the ‘Plugins’ menu in WordPress.
  3. Optionally, alter your theme’s 404.php template to list suggestions from Smart 404

Note: If you desire reporting on 404 errors that Smart 404 is unable to remedy, I recommend Joe Hoyle’s JH 404 Logger, which adds an item to your dashboard listing 404 errors. 404 Notifier by Alex King will send emails for 404 errors, but I hear reports that emails are sent for 404 errors that this plugin is able to recover from, not just unrecoverable errors.

Configuration

There are two configuration options for Smart 404:

Search

Turn on or off searching of posts, pages, tags and categories

Ignored patterns

A newline-separated list of terms or patterns to ignore from the URL. This is particularly useful for supporting old permalinks with an ID number in them. For example, to work with URLs like:

123-post-title.html

Add the regular expression pattern:

^[0-9]+-

This will ignore all numbers, followed by a hyphen, at the start of the URL.

Template Configuration

To provide a helpful list of suggested posts in your 404 pages, modify the 404.php template in your theme to use a Smart 404 template tag. For example:

<?php if (smart404_has_suggestions()) : ?>
Try one of these links:
<?php smart404_suggestions(); ?>
<?php endif; ?>

Or, for something a little more complicated:

<?php if (smart404_loop()) : ?>
<p>Or, try one of these posts:</p>
<?php while (have_posts()) : the_post(); ?>
<h4><a href="<?php the_permalink() ?>"
  rel="bookmark"
title="<?php the_title_attribute(); ?>">
<?php the_title(); ?></a></h4>
  <small><?php the_excerpt(); ?></small>
<?php endwhile; ?>
<?php endif; ?>

Note that smart404_loop() will only work for posts, not pages, due to limitations in the loop mechanism. Several template tags are supplied by Smart 404 for use in the 404.php template:

smart404_has_suggestions

Returns true if there are some suggestions, false otherwise

smart404_get_suggestions

Retrieve an array of post objects for rendering manually.

smart404_suggestions

Draw a list of suggested posts.

Pass the parameter “list” to render suggestions as a list.

smart404_loop

Query posts for use in a Loop. See the second example above for usage. Note that smart404_loop() will only work for posts, not pages, due to limitations in the loop mechanism.

, , , . Bookmark the permalink. Both comments and trackbacks are currently closed.

43 Comments

  1. Posted February 20, 2009 at 11:17 am | Permalink

    Not working for me in 2.7.1. I enabled the plugin (v 0.3), added “” to 404.php, and verified that “Posts” is checked on the settings page. Any other things to try?

  2. SimWhite
    Posted March 3, 2009 at 7:01 pm | Permalink

    I have the same probles as ryan. Plugin don't work with 2.7.1.

  3. Posted March 4, 2009 at 3:42 am | Permalink

    This started working for me after a day or so. Like, magic! :)

  4. Posted March 19, 2009 at 6:25 am | Permalink

    I got the same problem. Not working on 2.7.1, at least I notice no effect whatsoever… what could be going wrong?

  5. david w.
    Posted March 24, 2009 at 4:04 am | Permalink

    This is working for me in 2.7.1 on a Sandbox based theme with the full loop in my 404.php file.

    But, my site is a migration from a handcoded aspx site where all blog posts had a url like: blogs_Blog Title.aspx and Smart404 is not detecting the blog title to give a good match unless I strip out the blogs_ part of the URL.

    Is there a way I can change the smart 404 behavior to ignore the "blogs_" – I've tried adding blogs_ and .aspx to the ignored terms but that doesn't help as I believe it's controlling the search index, not the incoming search terms to detect.

    Thanks, David

    • Posted March 24, 2009 at 9:16 am | Permalink

      Hi David,

      Adding blogs_ and .aspx to the ignored terms is exactly right – I'm not at all sure why it wouldn't be working for you. Did you enter each on a new line?

  6. david w.
    Posted March 24, 2009 at 10:57 am | Permalink

    Thanks.

    I just tried it again and it's not working, you can see for yourself: http://soiveheard.com/blogs_Felsenstein.aspx results in the standard 404, but http://soiveheard.com/Felsenstein gives me the Super404 resutls.

    I've tried turning off caching thinking that could be the issue, but it doesn't see to make a difference.

  7. david w.
    Posted March 24, 2009 at 11:18 am | Permalink

    I take back the part about seeing for yourself, I've since gotten around it with a little mod_rewrite, but I'd still like to figure this out if you can.

    I can turn off the mod_rewrite if you'd like to see it not working too.

  8. Posted March 30, 2009 at 12:20 pm | Permalink

    For those of you working with other plugins that use the tags on titles like <!– :en –> for other languages or hat ever, you need to change this line for it to display right – add the "_e()" function:

    Line # 229 in smart404.php:

    <a href="<?php echo get_permalink($post->ID); ?>"><?php echo $post->post_title; ?></a>

    to:

      <a href="<?php echo get_permalink($post->ID); ?>"><?php echo _e($post->post_title); ?></a>
    

    • Posted March 31, 2009 at 9:22 am | Permalink

      Thanks for the tip, Moonsand – I've fixed up the HTML and removed the other comments. For future reference, all of the <, > chars, etc, are escaped automatically (as other commenters were assuming this was already happening, and it was mucking things up)

  9. Posted March 31, 2009 at 8:21 am | Permalink

    Moonsand, can you make a picture with this exact code? I dont understand this :) Waiting for link :)

    • Posted March 31, 2009 at 9:24 am | Permalink

      Nemezis, you can open up the 'smart404.php' file in a text editor of your choice (you may want to FTP it to your local computer for editing first, then FTP it back in place afterwards); find the line Moonsand indicates (just search for it if you don't have line number markers), then copy the replacement line and paste it over the original.

  10. Posted March 31, 2009 at 3:03 pm | Permalink

    Basically wrap the "$post->post_title" inside "_e()" like this: "_e($post->post_title)" this will make wordpress "evaluate" the text and output the correct text according to any other plugins that need to modify the text like qtranslate.

  11. Posted March 31, 2009 at 5:31 pm | Permalink

    Got it! I think this could be helpful ;) Thanks very much!

  12. Posted March 31, 2009 at 11:56 pm | Permalink

    Here is what i use in my 404. From GOOGLE:

    <code> <script type="text/javascript"> var GOOG_FIXURL_LANG = 'en'; var GOOG_FIXURL_SITE = 'http://sports2all.com/&apos;; </script> <script type="text/javascript" src="http://linkhelp.clients.google.com/tbproxy/lh/wm/fixurl.js"></script></code&gt;

  13. Posted April 1, 2009 at 6:44 am | Permalink

    SuperMAG, can you tell us more about this code please? What it does?

  14. Posted April 22, 2009 at 1:44 pm | Permalink

    Hi, Thanks for your plugin.

    I am using WP 2.7.1 and your plugins works fine.

    After installation, I've changed my permalinks (removing yyyy/mm/dd) and when I go to my old link (the one with yyyy/mm/dd), it's just redirect it to the new link.

    I also customize my 404 error page using your smart404_loop and it works beautifully. Sample error page: http://www.tamanroyal.com/living-room.html

    Thanks once again.

  15. Posted April 26, 2009 at 9:01 pm | Permalink

    Hello, Michael, thank you very much for this plugin. It really works. it was what I needed. The next thing you should do is combining it with an 404 alarms system just like from Alex King: http://alexking.org/projects/wordpress/readme?project=404-notifier Juergen

  16. Posted April 26, 2009 at 9:06 pm | Permalink

    A small bug I think this works: -> <p>Or, try one of these posts:</p> <?php while (have_posts()) : the_post(); ?> <h4><a href="<?php the_permalink() ?>" rel="bookmark" title="<?php the_title_attribute(); ?>"> <?php the_title(); ?></a></h4> <small><?php the_excerpt(); ?></small> <?php endwhile; ?> <- this won't, gives you no result <?php if (smart404_loop()) : ?> <p>Or, try one of these posts:</p> <?php while (have_posts()) : the_post(); ?> <h4><a href="<?php the_permalink() ?>" rel="bookmark" title="<?php the_title_attribute(); ?>"> <?php the_title(); ?></a></h4> <small><?php the_excerpt(); ?></small> <?php endwhile; ?> <?php endif; ?>

  17. Posted May 14, 2009 at 1:20 am | Permalink

    Hello, Michael. Thank you for such a valuable smart 404 plugin.

    I have a problem in excluding thank you pages by "Ignored patterns". I want to exclude url at http://www.az-net.com/about/thank-you-order/, and I have tried to set the Ignored patterns field like "-order/$", "order/$" or "thank-you" per line but the url is still shown (i.e at http://www.az-net.com/thank-you ). Did I make a mistake? Any help would be really appreciated.

    Thanks,

    • Posted May 14, 2009 at 11:36 am | Permalink

      Hi Hideki,

      It looks like you’re trying to omit a page from the 404 results – this isn’t actually what ‘ignored patterns’ is for. Sorry, that’s probably bad documentation on my behalf. The ignored patterns setting is there to ignore certain text from the URLs. For example, if your old permalinks looked like “/203-some-post-title.html”, then you want to ignore the number at the start, and the .html at the end (actually the .html is a built-in ignored pattern, so you don’t need that) – so you’d have a pattern like “^[0-9]+-?” to ignore one or more numbers at the start followed by a hyphen.

      There’s currently no way to omit items from the 404 results, although you can do that fairly easily in the loop, something like:

      <?php while (have_posts()) : the_post(); ?>
        <?php if ( in_array(the_ID(), array(100, 101, 200, 230) ) ) continue; ?>
        ...Rest of list HTML goes here...
      <?php endwhile; ?>

      This would exclude posts/pages with the ids 100, 101, 200 or 230.

      • Posted May 15, 2009 at 4:50 pm | Permalink

        Michael, thank you very much for your reply.

        I tried to add the codes but I still can't fix my problem. I should know how PHP works and then I may try with my poor PHP knowledge. I would really appreciate if I may hear which I must change the codes, the 404 template or the plugin itself.

        Thanks,

        • Posted May 18, 2009 at 10:16 am | Permalink

          You'll want to edit 404.php in your theme – see the readme for Smart 404 for more info on the process. Best of luck!

          • Posted May 19, 2009 at 10:40 pm | Permalink

            Michael, thank you very much for your kind.I will try it. Thanks,

        • tyler
          Posted June 7, 2011 at 9:18 am | Permalink

          Hi – where does the script actually go in the 404 template?

          Thanks,

          Tyler

  18. Posted May 14, 2009 at 1:51 am | Permalink

    Hello, I hope the server environment may be a hint.

    FreeBSD 7.1-RELEASE-p5 i386 Apache/1.3.41 PHP 5.2.8 MySQL 4.0

    Thanks,

  19. Posted May 14, 2009 at 3:53 am | Permalink

    Plugin works fine. But I noticed that when the old permalink with /trackback is accessed, it gives 404 error. Google and other search engine have indexed my posts with /trackback, but when visitors clicked that it gives 404 error. But when accessed without /trackback it redirects with the new permalink. how do i fix this? Please help me. thanks!

    • Posted May 14, 2009 at 11:28 am | Permalink

      Good catch! You're right, this is something I'd missed. Version 0.3.2 just released fixes this.

  20. Posted May 14, 2009 at 4:00 pm | Permalink

    0.3.2 works fine with the /feed/ it d0esnt give any 404 error, but still noticed that there is still a bug on /trackback/ it still gives an 404 error. Please check on this. Thanks!

  21. Posted May 17, 2009 at 8:08 pm | Permalink

    Hi,

    I'd just changed my permalink and changed .htm to / and the plugin works fine, it is now redirecting my old permalink to the new ones.

  22. Posted June 7, 2009 at 6:25 pm | Permalink

    I'm experimenting with your plugin now. I wish it could include pages but it's still useful otherwise. I found a function to display the URL on page but this might be something you could add to the plugin itself. Thanks for this!

  23. Posted June 7, 2009 at 6:51 pm | Permalink

    Oh! One question – is there a way to display a message if there are no suggestions?

  24. Posted June 10, 2009 at 7:27 pm | Permalink

    Hi Cole – certainly. Something like this should do it:

    <?php if (smart404_loop()) : ?> <p>Or, try one of these posts:</p> <?php while (have_posts()) : the_post(); ?> <h4><a href="<?php the_permalink() ?>" rel="bookmark" title="<?php the_title_attribute(); ?>"> <?php the_title(); ?></a></h4> <small><?php the_excerpt(); ?></small> <?php endwhile; else : ?> **There were no suggestions** <?php endif; ?>

    • Posted June 10, 2009 at 8:56 pm | Permalink

      A combination of being tired, dense and generally unfamiliar with PHP has me stumped. Is there something more specific to make that work? With the added else, it still just displays most recent posts in the loop when no relevant entries are found.

  25. Posted June 10, 2009 at 9:36 pm | Permalink

    I work with WP 2.7.1. I’ve opened my 404.php and below my normal text concerning the error message 404, I’ve put . But nothing happens. The error page for itself works, but no suggestions are shown.

  26. Posted June 10, 2009 at 9:37 pm | Permalink

    Again, the code has not been shown in my post above (before and after are the breaks, of course): ?php smart404_suggestions() ?

  27. Posted June 10, 2009 at 9:41 pm | Permalink

    No suggestions, I have put in your code of configuration the theme as mentioned above, but … nothing to see: http://kunstblog.birgit-heinz.de/2009/04/ueber-die-kunst-kunst-zu-verkaufen2/

  28. Posted June 15, 2009 at 10:09 pm | Permalink

    Okay, something is not right.

    Using WP 2.8

    Your plugin seems to have issues with .html at the end of URLs

    If I go to http://www.sanglier.co.uk/baking, it finds my couple of articles with baking in them.

    If I try http://www.sanglier.co.uk/baking.html, then it cannot find any results and just puts up the most recent posts.

    I notice that the script is meant to be removing the .html, but I assume this is not happening?

    Help?

    • Posted June 16, 2009 at 7:07 pm | Permalink

      Hi Joss,

      What do you see if you put the following debugging statement into smart404.php on line 55, just before the line if ( in_array( 'posts', (array)get_option( 'also_search' ) ) ) {:

      echo "search: $search";

    • Posted June 16, 2009 at 7:28 pm | Permalink

      Ah! I see the problem. In a few minutes, version 0.3.3 will appear – update and it should solve that.

  29. Posted June 16, 2009 at 7:18 pm | Permalink

    Hi Michael

    It tells me it is searching for “baking.html”

  30. BAC
    Posted June 28, 2010 at 12:30 pm | Permalink

    Hi Michael,

    Like Smart 404 a lot, shame it does not work for pages. That would make it ideal for a CMS implementation of WordPress which is predominately page based.

    Is this something you are going to look at?

    Maybe something that might be of interest: Yoast’s search suggest plugin uses the Yahoo spell check API to offer suggestions for mistyped searches. Awesome for usability and site stickyness.

    Could this be used to output suggestions based on the url entered? Could that then be used to output suggested pages in a page loop?

    I think wordpress’s future is as a full blown CMS. Food for thought.

    Cheers BAC