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:
Download
Get Smart 404 over at the Smart 404 WordPress Plugin page!
Installation
- Unzip the package, and upload smart404 to the /wp-content/plugins/ directory on your WordPress site.
- Activate the plugin through the ‘Plugins’ menu in WordPress.
- 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.
Related posts
- Private Tags WordPress Plugin The “Private Tags” WordPress plugin allows users to specify a...
- Smart redirects A PHP script to be placed in media/upload directories to...
- Keeping blog visitors by showing meaningful search results in WordPress By default, Wordpress will show you full, confusing posts when...
- “Elegant Grunge” WordPress theme An unwashed yet crisp Wordpress theme with a feature footer,...




215 Comments
ah, thought it was me being a tool!
Having played with the plugin a little more, for future releases maybe you would consider outputting the suggested pages as a list rather than divs as it’s easier to format
Also adding relevancy to results would be cool. For some reason the most relevant page /post always seems to be the last suggestion, could be just fluke. I shall test more.
Cheers BAC
http://yoursite.com/?p=1
will give you this error message:
Warning: strpos() [function.strpos]: Empty delimiter in /directory/wp-content/plugins/smart-404/smart404.php on line 87
I’ve rolled in a fix for the next version, but for now if you like, you can add the following line just before line 63 (the $GLOBALS… one):
‘if ( !trim($search_words) ) return;’
“Also adding relevancy to results would be cool. For some reason the most relevant page /post always seems to be the last suggestion, could be just fluke.”
I concur. It’s not a fluke. I’ve tested this plugin on two sites. It’s a nice plugin, but it always shows the same irrelevant suggestions at the top of the list, but the suggestions at the bottom of the list are very relevant. Any way to turn that around?
tks you for your so good plugin
Thank you for a great plugin. However I had some problems when I installed it on my blog. When misspelling the url to a Page it didn’t work and ended up in endless redirect until firefox stopped it. I had a quick look in the code and found the error
On line 100 it says
wp_redirect( get_page_uri( $pages[0], 301 ) . $get_params );, I changed it towp_redirect( get_permalink( $pages[0]->ID) . $get_params, 301 );and now it works.And secondly if a page and a post have the same words the post will always be prioritized and the user redirected. I would like it to be the other way around. Or maybe even show the 404-screen for the user and let them pick between the page or the post. It would have been nice with an option in the administration menu to solve this?
tks you because i had disable the plugin for the same problem as you. but i hope this work and stay as that for the next version, i am going to try your form
follow : fatal error
Thanks for the catch, Emil!
I’ve just released a fix, and also added the new feature of being able to prioritise, as you say. Let me know what you think.
Cheers, Michael
Or maybe even show the 404-screen for the user and let them pick between the page or the post. It would have been nice with an option in the administration menu to solve this?
Agree wholeheartedly! I’d rather have the links than the redirect.
Thanks for the quick response. I just downloaded the new version and the reordering is really nice. Unfortunately there is still a bug when redirecting pages. In the same function the “)” is in the wrong place
wp_redirect( get_page_uri( $pages[0] . $get_params, 301 ) );should bewp_redirect( get_page_uri( $pages[0]) . $get_params, 301 );. But when I try it, I can’t get the get_page_uri() to work either, but when I change it to get_permalink it works fine. Here is my version of line 104:wp_redirect( get_permalink( $pages[0] ) . $get_params, 301 );If you have a public repository anywhere, like github and want some help maintaining the plugin I would love to contribute. Keep up the good work.
Damn! I hate it when that happens! I had some issues with symlinks and versioning and that slipped through. Been a long day =)
Thanks again.
I’d be very happy for you to contribute! I’ve emailed you
Great tool! I love it and works well at 3.5 with WP3.0 However, on 4.0 and 4.0.1, I get a “Array()” in text at the top of the page… so downgraded again. Keep up the great work! Alban
That is fixed in 4.0.2. It is working perfectly now :)
Phew. Thank god – I shouldn’t be allowed outgoing network communications when I have days that my brain doesn’t work properly ;-)
Sweet, it works like a charm indeed! Thanks guys!
Hello,
I just started using your plugin and I like the functionality, however I was wondering if you could add a configuration option that stopped the automatic redirect. For my personal taste, I would rather the user get taken to my 404 page and be given the list of suggestions, rather than the auto redirect.
Just a thought. Thanks Paul
Hi Paul,
I’ll certainly consider it – for now, though, you can open up
smart-404.phpand comment out (prepend with “//”) all instances of “wp_redirect ( ...” and the immediately following “exit();” lines.Hi Michael
I too would like this feature to be available, i.e. being able to choose whether to redirect automatically or not.
Automatic redirection can sometimes be confusing for search engine crawlers.
My logs suggest that sometimes request for category pages that no longer exist (because the category has been renamed) are now redirected to some post on my blog, because the last few letters of the URL match. This can be confusing from a SEO point of view.
For now I have done what you suggested (commenting out calls to wp_redirect() and exit()).
Thanks again for this great plugin!
Regards
Vijay
I had a second idea.
You could use much of your plug-in’s functionality to help out on the search result page as well.
Some plug-ins give spelling suggestions, but that can lead to suggesting words that aren’t even used in the blog…your plug-in could return suggested posts/pages. “similar posts” if there were some results and “suggested posts” if there were no results
Hmm, maybe one day =)
Sounds useful, will need to try this the next time I’m updating my site. Thanks in advance! :)
It works pretty good. I put the suggested posts code into my 404.php page.
http://www.houseofannie.com
What would be pretty cool is if the plugin tracks which of the suggestions gets clicked on and adds it to its search algorithm so that if say 5 or 10 people click on the same suggested link from the 404 page, it then automatically redirects to that page the next time instead of serving up the 404 page.
Great idea, Nate – I’ll put it on the list
I hate to ask because it’s one of those dumb things I should be able to figure out myself, but is there anyway you could add a basic example of how to access the object returned by smart404_get_suggestions and output a few of the results? I amaze myself at my ability to do something ridiculously complicated, then get hung up for days on something that should be pretty basic. But then again, that’s kind of the fun of programing.
Either way though, thanks for the great plugin. I love how it auto 301 redirects to the most relevant match, which saves me some trouble writing redirects if I change my permalink structure.
Hi Jason =)
The best way to output results is as in one of the examples above under the ‘Template Configuration’ section;
smart404_get_suggestions()just returns an array of posts, but it’s easier to just use the loop helpers the plugin provides.I’m sorry for appearing a bit dense. From the help and the examples, I can’t seem to get the plugin to do anything other than display the latest posts?
I’m running the latest version of Smart 404, and the latest of WordPress, but it doesn’t appear that the plugin’s actually working. It’s active and configured, but things that should be returning posts (year/month/day/post_name.html to year/month/post-name/) aren’t working. They worked on 3.0, so I’m wondering if you might point me in the direction of things to look at. Note: I haven’t made any major changes to WP or to the plugin since upgrading either.
Great plugin. I’ll be adding it to my site as soon as I can… Should help fix the problem I have after removing a large section of my site.
Good job :)
Found another bug (or actually more like a left out condition). Basically, if you run a .html, it will actually run the parsing and do the smart 301 redirect. If you use the same URL but with .php, it’ll just drop the entire search itself and won’t do a comparison.
All I did to fix this is add in: $patterns_array[] = “\.php$”;
And that does the trick.
Interesting. Mine doesn’t seem to want to play nice with URLs containing underscores (apparently it threw off my earlier comment re: .html extensions). http://example.com/year/month/day/post_name.html throws 404, but http://example.com/year/month/day/post-name.html doesn’t. This only since upgrading both the plugin and wordpress.
I don’t know what’s happening there, James. You could try doing some debug printing to see what’s going on; maybe insert:
On line 63, after $search_words = preg_replace( "@[_-]@", " ", $search);
Did that. Now it just gives me a standard 404 error page and presumedly dies. I’m assuming I should be seeing something in the server logs? If so, not in error.log.
Okay, killing the exit statement from your debug line gives me what I suspect is the result you’re aiming for and doesn’t result in the script just dying and not giving me anything but the standard apache 404 error. Here’s the thing. Let’s take an example post of mine from 2006, because that’s the one I tested this on as I’d been using the old permalink structure back then. Going to http://www.the-jdh.com/2006/07/23/well_its_been_2_weeks.html produces 404, as it should–the link no longer exists. The array returned is this.
For whatever reason, it’s deciding not to redirect me to where I should be (http://www.the-jdh.com/2006/07/well-its-been-2-weeks/). But, yet, if I replace the underscores in the URL with WordPress’s default of dashes, and leave the rest of the URL exactly as it was in the old structure, it behaves normally.
Is it possibly to do with the fact the underscore’s not being properly escaped, or do I have to add something to the search preferences to get it to play nice? Again, this only started happening since I upgraded both the plugin and WordPress to their respective latest versions.
Ah! I think I know what it might be.
Open up smart404.php again, and around line 60-something, find the line:
Then immediately after it, add the line:
$search = str_replace("_", "-", $search);That works, at least for now. Thanks! Will that be in the next version?
Yep; I’ve already submitted it
The other possibility is to add .php$ to the patterns in preferences =) I’ll add it in in the next version, though
Hi thx for great contribute. I found its not working for Hebrew letter, ie http://www.domain.com/מגניב will keep redirect to plain 404 error page. will you consider sove that in the next update?
cheers Kobi
Hi Kobi, I’m afraid I have no idea why it wouldn’t be working with unicode characters; is your webserver correctly configured?
Hi Michael, basiclly I use Permalink in Hebrew and it works fine. but when I try to test the 404 plugin I get errors from your plugin - the error is: Warning: strpos() [function.strpos]: Empty delimiter in /home/dhgonobi/public_html/iboss.co.il/wp-content/plugins/smart-404/smart404.php on line 87
you can see it here – http://www.iboss.co.il/%D7%A7%D7%95%D7%91%D7%99 or a screenshot here – http://screencast.com/t/MDdlMGRhYW
thx Kobi
Ah, that helps, but I’m still baffled. For debugging, open up smart-404.php, and add the following above the line $GLOBALS["__smart404"]["search_words"] = explode(" ", $search_words);:
print_r(array("request" => $_SERVER["REQUEST_URI"], "decoded request" => urldecode($_SERVER["REQUEST_URI"]), "search words" => $search_words));did that now I get this – http://screencast.com/t/ZWZjNjRiNDct (screenshot)
I suspect perhaps your PHP installation may be incorrectly configured, perhaps; In my tests, it all works perfectly. I’ve made a test script which works perfectly for me, and prints out:
Download this script and save it on your webserver somewhere (call it something like test.php), and open it in your web browser to see what happens. It should give the same output as the above. If not, it’s your PHP installation.
Hi I did it, and got: string(25) “/%d7%a7%d7%95%d7%91%d7%99″ string(9) “/קובי” string(0) “”
is this means something wrong with my server? can you give me a lead about it so I can ask tech support to fix it please?
Yep, definitely something wrong with your setup. Just point them at this conversation, the test script, and the expected output in particular; they should be able to figure it out from there. They probably just need to update PHP, or perhaps do something like make sure they’ve built unicode support in.
Hi,
Not being a PHP person I am not sure how to do this myself, but what I would like is that if it can’t direct to a page, when it brings up the search box, it also gives a link to the home page and automatically redirects after a set time.
Or just if it can’t find a page rather than giving a choice, just comes up with “sorry that page is not found returning you to the home page”
Apart from that a great!! plugin :) cheers and thank you for you work
Aaron
Hi Aaron, You can just edit the 404.php template in your theme to do what you want. Probably add a timed redirect as a meta tag. If it were me, I’d do something like this:
Your a star cheers for that :)
I can see I will just have to add PHP as another item on my “to learn” list :)
thank you
First off can I just say what a great plugin you’ve created!
Like Paul, I too would love an option that stops all the automatic redirection.
I’ve also noticed an error – line 99 should be:
$GLOBALS["__smart404"]["suggestions"] = array_merge ( (array)$GLOBALS["__smart404"]["suggestions"], $posts );
otherwise, if you prioritise pages over posts, you never see any page suggestions as the array just gets overwritten.
Ah, great catch, Mark – thanks. I’ve released the fix in an update.
thankyou!
This plugin is amazing. I have over 3600 pages @ 404 because of a move and this thing redirects them to the new link instantly.
Peace and <3 Brother Shahin @ Dprogram.net
Hey Michael, great plugin. Thanks for it!
I’ve noticed that it seems to be having trouble finding one of my pages. I have a page on my site named shame, at http://cfs-survivors.org/emotions/shame. I would expect this to be the target the bad url: http://cfs-survivors.org/shame. Is there a problem locating pages in a heirarchy?
Cheers, Graham
Hi Graham, In a couple of hours, try downloading the development version, which should show up as version 0.5 at the top of smart404.php (if not, wait a bit longer for it to appear), and let me know if that fixes things.
Cheers! Michael
Thanks Michael; yes, the development version fixes the problem nicely.
When I updated to .5, it just stopped working. No results showed at all. the 404.php changes were still there. I reverted back to .4 and it works fine…I don’t even know where to start troubleshooting…php version 5.
Sorry to hear that, Josh – what have you got in the plugin’s settings, to start with?
nothing in the ignored patterns box and all the others checked. Should I try just posts checked?
I went ahead and updated back to .5, tried just posts, just tags, etc and still nothing on the results when i go to any page that doesn’t exist, like http://joshuadhall.com/123 or /josh
Hmm, that’s rather baffling. If you feel up to it, download this test version (Move away smart404.php and put this in its place) and give it a whirl – let me know what it produces.
Search: [123] Search groups: [Array ( [0] => tags ) ]
here is what I have in my 404.php file. It’s a copy and paste from your website:
Or, try one of these posts:
<a href="” rel=”bookmark” title=”">
hmm…guess it didn’t like that code:
Or, try one of these posts:
<a href="" rel="bookmark" title="">
</code?
haha, 3rd times a charm! i need a preview or edit or something!!
Or, try one of these posts:
<a href="" rel="bookmark" title="">
Haha, yeah, you need to escape the HTML entities.
It looks to me like you only have tag searching enabled. Have you tried going in and re-saving your settings?
Search: [123] Search groups: [Array ( [0] => tags [1] => posts [2] => pages [3] => categories ) ] Searching: [Array ( [s] => 123 [post_type] => post ) ] Results: 2 posts Posts search results: [2] Searching: [Array ( [s] => 123 [post_type] => page ) ] Results: 0 pages Pages search results: [0]
That looks more like it – now you just have to make sure your 404 page is working. You could try pasting the source using pastebin.com and posting the link here.
http://pastebin.com/NVe2NQnp
Okay, that looks right.
Open up smart404.php again, find “function smart404_loop() {“, and on the next line, add:
Then try again and see what it says
same thing still…
Search: [123] Search groups: [Array ( [0] => tags [1] => posts [2] => pages [3] => categories ) ] Searching: [Array ( [s] => 123 [post_type] => post ) ] Results: 2 posts Posts search results: [2] Searching: [Array ( [s] => 123 [post_type] => page ) ] Results: 0 pages Pages search results: [0]
Ah, yes, I beg your pardon, I think I put an early exit in that debug version – revert to the original, then add that var_dump line.
alright, we got some output now…
now on 0.4.4, it came up with tons of results, but maybe with this “better” version, it will only find a few results.
in your design, if i literally to go /abfasdartragdfaryryarya34tasda32.html, should smart404 have suggestions or are there going to be times when it has no suggestions?
It’ll definitely be stumped sometimes – it’ll only give suggestions if there are actual matches
Hi there,
Has the latest version stopped the template code working? (the “or, for something a little more complicated” code) it used to offer a lovely list of alternatives but now just renders a page not found response.
TIA
HJ
Hey Howie,
Not that I’ve seen (it works fine here). Can you give me a little more info on your setup (URL showing problem, WP version), and paste your 404 page code somewhere (say, pastebin.com and link to it here)?
Thnx for speedy response!
http://pastebin.com/utiLkFCW
using wp Version 3.0.1
site here: campervans.biz/adsf
Hmm, do you actually even have posts that have the word “adsf” in them? That seems unlikely. If I try http://campervans.biz/engine it works fine.
hmmm, previously if someone clicked on an outdated link it would show a list of alternatives, here’s one that someone clicked on today:
http://campervans.biz/auto-sleeper-symbol-fiat-ducato-jtd-2-0-hdi-25000-miles/
Ah, I see! Actually, I’m a little baffled that worked in prior versions – it shouldn’t have; that URL does the equivalent of searching for “auto sleeper symbol fiat ducato jtd 2 0 hdi 25000 miles”, which is unlikely to return any matches unless the post matches all of those terms. The purpose of that feature is more to try to guess the correct post, under the assumption that one exists and is just being accessed at the wrong URL, rather than try to suggest similar posts.
Still, if the old version worked for you, I’d just revert to that one =)
Getting a PHP error … “Catchable fatal error: Object of class WP_Error could not be converted to string in /home/server/www/www/wp-content/plugins/smart-404/smart404.php on line 107″ when I try browsing to http://www.CADbloke.com/cad
If I add an extra letter to form larger parts of words (eg. ocad, cadb) it seems to have no problem.
I was trying all sorts of word combinations to try to get a list of posts but the plugin seems to be more aggressive at choosing a canonical place to go rather than presenting options in a list like it used to tend to do. Is there a setting to adjust this tendency?
Nice plugin, by the way.
… If it is trying to link to a category, the http://www.cadbloke.com/category/autocad/ category has 2 child categories, 1 with posts and 1 without but the parent category itself (the link) has no posts, directly. Perhaps it is a null-reference error ?
Sorry, ewen, I haven’t had a chance to look at it quite yet – I’ll take a peek soon.
The latest version doesn’t work at all for me either. I tried disabling all other plug-ins, and that didn’t help. The 404 script doesn’t show anything. Same with my other site at http://passivepromotion.com. It worked just fine before!
Could it be a conflict with the Thesis theme perhaps?
Due to lack of response, and my inability to get it to work, I’m trying to find the old 0.4.4 version to install. It’s a little embarrassing, since I just published a post on the 7 Best WordPress Plugins for Passive Promotion, including Smart 404, but had to not that it’s not working for me right now! :)
Sorry, Brian – I’m run off my feet at the moment and haven’t had a chance to look at it. Have you already reverted to 0.4.4? The plugin seems to be working on your site..
No worries! Yep, I found it by taking the new download link and modifying it:
http://downloads.wordpress.org/plugin/smart-404.0.4.4.zip
I also removed my little disclaimer from the post. Hope it helps earn you some well-deserved attention!
If I can help you troubleshoot, just say the word. Otherwise, I’ll try out 0.5.1 when it’s ready. :)
Ah, righto, no problem.
I’d definitely appreciate some debugging help; thanks – I’ll get in touch when I have a moment.
my blog also used to display a list of recent posts if a 404 page was not found for example if I added some random letters like “zzzzz” to the end of an url it would display a list of posts on my site. If the word had a similar meaning to one of my posts then it would just redirect to that page or category etc. The latter feature still works since I upgraded WP to version 3.1 but now if I type random letters in the url it just shows a 404 error too. It would be good if we could have that old feature introduced in the next update please. Even an option to turn it off & on in the Admin page.
I’ve installed and activated the plugin but the 404 page just comes up blank.
Is there something I’m doing wrong?
Hi there
It’s fixed now… I had the same issue as Brian…
I’m using version WP 3.0.1
I followed what Brian did downloading the older version and it’s works great.
Here’s the link to Brian’s comment: http://atastypixel.com/blog/wordpress/plugins/smart-404/comment-page-3/#comment-1951
Cheers MJ
I love Smart 404… thanks again for it! A quick question: is there any way to exclude certain pages from being a target? I know I can exclude all pages in the options settings, but I just want to exclude one or two. I have a couple of sales landing pages which should only be shown as the result of a sales funnel process, and I don’t want Smart 404 to inadvertently display them. Cheers, Graham
Not currently, I’m afraid, Graham – the plugin could be tweaked to avoid certain pages by adding something like
if ( in_array($posts[0]->ID, array(array, of, post, ids, to, avoid) ) { return; }in some strategic places, though (mostly, before the wp_redirects for posts/pages).Ok; I think that’s a bit beyond my PHP skills. How much would I need to donate to get this feature added to the plugin please? Thanks, Graham
This is a really great plugin! Amazing work!
But I still think the pattern matching can be made better.
I have a case where a thread on a forum (URL: http://www.thinkdigit.com/forum/online-services/131295-team-bhp-suck-com.html) has a link to one of my blog posts. However, for some reason, the link has been truncated (with …), and therefore whenever someone clicks on it, they get a “404 Page Not Found” error on my blog.
But there are still unique words on that link in the non-truncated part, which can uniquely identify the correct blog post, but that doesn’t happen.
The truncated link is:
http://www.vijaypadiyar.in/blogs/200…w-joinees.html
And the correct link is:
http://www.vijaypadiyar.in/blogs/2009/07/team-bhp-harassment-for-new-joinees.html
No other post on my blog has the word “joinees” in the URL, so it should be possible to redirect to (or at least find) the correct post.
One more request: could you please add a feature to notify (by email) the blog administrator whenever a 404 page is served? This would let admins know if something was messed up on their blog. Of course, it should be possible to turn the feature on and off.
Regards
Vijay Padiyar
I was having some unicode type problems and this fixed URLs that showed up like this:
/%E2%80%8Bthe-name-of-the-page
Hooray!
But if the messed up part is in the middle of the URL, then it does not seem to work, so for something like this:
/the-%E2%80%8Bname-of-the-page
I tried fixing this in htaccess but then figured out that the page URL was being passed to WP (and subsequently giving me a 404 page with my site’s theme), so I figured the fix had to be with a WP plugin. This plugin has come the closest so far – fixing one page but not fixing the remaining 4. This: “%E2%80%8″ seems to be in each URL. Any ideas?
Hi,
It saved me after changing permalinks structure. A huuuuge thank you!
2 Trackbacks