First of all, the trick that I'm going to reveal could work on any website and not only WordPress. But keep in mind you will need some website development knowledge to understand the article. I'll try to explain the process in detail, but at some point, I had to take decisions for this article not to be 22 pages long! So for instance, I'm considering you know how to load a custom javascript file, install a new library if needed, etc. If you have a question, feel free to write it in the comment section.

The facts

It's not a breaking news to tell you that spam creators and haters are in war basically since the birth of the Internet. This is a great deal and a lot (really, a lot) of money is both generated and wasted on this.

For spammers (not speaking about email), it's just about finding forms on forums and news websites which they can automate (using bots, etc.) advertisement or fishing.

WordPress and it's comments feature is of course the target of spammers. So by default, WordPress is provided with an incredibly efficient plugin for spam: Akismet. Once set up, Akismet will detect if a new posted comment is spam or not and depending on your settings, silently discard the worst and most pervasive spam or put it in the Spam folder for review (auto deleted after 15 days). Akismet is so smart (thanks to it's huge database) to detect those spams that all people live with it.

But for me, something is still wrong: this doesn't prevent bots to post. For each bot actions, there are a huge number of requests made on your website. Those for accessing your website, those for posting a comment, those for Akismet to deal with it, etc. What about preventing bots to physically access your comment form and post (or at least try)? This would save quite some processing time.

How to drastically reduce WordPress comment spam

Extract of my Akismet stats for the past two years

[tkp_image width="960" alt="Akismet Tazintosh Statistics" zoom="no" exif="no" shadow="no"]AkismetTazintoshStats.png[/tkp_image]

Starting June 2015, I've updated my website to try out a simple trick (using the .htaccess file) found on internet to prevent bots to directly load the comment form wp-comments-post.php. As you can see, from june to august 2015, it had some effects.

But in September 2015, I've added to this a personnal modification made on my own theme. Was just a try but results above are, I guess, self explanatory.

In fact, the trick is quite simple. If you have not done it yet (else refresh your browser), scroll down this page until you reach the end of this article, you'll notice that the comments and the comment form are not loaded. As soon as the scroll view start revealing the area where the comments should be, an Ajax request is sent to load the comments and the form. Scrolling is something bots don't do, so obviously, when visiting this page, there is no form to post on. Boom, simple.

Of course, the scroll based triggering is a choice by design. It obviously means that if your post content is to small or someone's browser window too high, the comments section will instantly reveal. So this scroll based solution cannot prevent “all” spam to be catched, but that's fine for me as you have to consider and put on the balance the usability for your readers. An instantly “more restritive” way would be to trigger the loading by asking the user to click a button. All of this is up to you to decide.

Let's do some killing!

Step 1: .htaccess. Prevent direct access to comment form

Here's the code you must add to the .htaccess file located in your WordPress website root. Change the to your own website domain (line 9).

Step 2: Ajax trick

You'll have to edit some of your theme templates. If like me, you've created your own theme from scratch, it will be even easier. But basically, the point is to prevent the comment section to be generated on PHPs files. Most of the time on a theme, comments are loaded into single.php and page.php files (see the WordPress Codex to learn more.

Preventing default loading of comments

Search for something like the following on each of your related template files (could be sightly different):

Comment those lines or delete them. Remember that if you're modifying a theme which is not yours, each update will remove your changes. I leave up to you the care of dealing with this: Either make some backups, either start using subversion, etc.

Once these modifications are done, if you refresh your website, comments should'nt load anymore. Now, we need to set modify your theme comments.php and create a new function that the Ajax will be able to call.

Modifying comments.php

If you look for this file on default themes like twentyfifteen, twentyfourteen, twentysixteen, it basically contains the <div id="comments">[…]</div>. Well, we'll surround this by a new function and replace lines 14 to 16 with your template comments code.

Now, we need to set up a javascript function that will load this template in Ajax, only when needed. If you're using a theme that support custom javascript, this is probably where you'll have to put this code.

Loading comments section with Ajax

The following is just the Ajax part that loads the comments section.

Note: In order to provide the right comments, the related ID must be passed to the PHP function through the Ajax call. To do so, I've updated my header.php file to automatically generate the corresponding ID:

Depending on how you want to load your comment section, you'll have to add your own code for triggering this action. Here's an example of the typical usage on this website (require ScrollMagic):

That's it… I guess. We've added a rule to the .htaccess file to stop bots from directly accessing the comment form, we've modified a theme template to prevent comment section being generated by default and we managed to do this via an Ajax request, only when needed. From now on, I see no reason for you not to have statistics similar to mines. Enjoy your spam free website!