Eliminate spam with a custom honeypot

A custom honeypot is a simple and effective way to eliminate spam. If a hidden field in your form is filled in, you can be fairly confident the submission is spam.

WPForms does include a built-in honeypot, but now that the plugin is used on millions of sites, most spam bots have been updated to identify and skip the WPForms field with a name of hp.

Your custom honeypot is different. It’s unique to your form and looks like any other field to a bot. I have pretty much eliminated spam on my contact form with a custom honeypot.


First, come up with a unique CSS class name you’ll use to identify your honeypot field. Make it something unique to your site (ie: not honeypot). If your class is my-fancy-field, add this to your theme’s stylesheet to hide that field.

.wpforms-container .my-fancy-field { display: none; }

Create a field in your form and add your custom class to it.

Add the following code to your theme’s functions.php file or a Core Functionality plugin. If this field is ever filled in, the submission will be marked as spam and have a honeypot message of “[Custom honeypot]”.

Make sure you update the $honeypot_class variable at the top to use your custom class name.

/** * WPForms Custom Honeypot * * @author Bill Erickson * @link http://www.billerickson.net/eliminate-spam-with-a-custom-honeypot/ * * @param string $honeypot, empty if not spam, honeypot text is used in WPForms Log * @param array $fields * @param array $entry * @param array $form_data */ function be_wpforms_custom_honeypot( $honeypot, $fields, $entry, $form_data ) { $honeypot_class = 'my-fancy-field'; $honey_field = false; foreach( $form_data['fields'] as $form_field ) { if( false !== strpos( $form_field['css'], $honeypost_class ) ) { $honey_field = absint( $form_field['id'] ); } } if( !empty( $honey_field ) ) { $honeypot = 'Custom honeypot'; } return $honeypot; } add_filter( 'wpforms_process_honeypot', 'be_wpforms_custom_honeypot', 10, 4 );

Logging

You can also enable logging so you can see if the honeypot is working. Every time a spam entry is submitted, this will create a post in the wpforms_log post type with the honeypot message and the full submission.

I recommend only logging this data temporarily because you don’t want to fill up your database with a bunch of unimportant spam messages.

First, update the wpforms_logging option to log spam:

/** * Enable logging of spam * */ add_action( 'init', function() { $debug = get_option( 'wpforms_logging' ); if( empty( $debug ) || ! in_array( 'spam', $debug ) ) update_option( 'wpforms_logging', [ 'spam' ] ); });

Use this code to make the WPForms Log post type visible. You can then access it in WPForms > Logs.

/** * Make log visible * */ add_filter( 'wpforms_log_cpt', function( $args ) { $args['show_ui'] = true; unset( $args['capability_type'] ); return $args; });

Bill Erickson

Bill Erickson is a freelance WordPress developer and a contributing developer to the Genesis framework. For the past 14 years he has worked with attorneys, publishers, corporations, and non-profits, building custom websites tailored to their needs and goals.

Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk

Reader Interactions

Comments

  1. Hans Schuijff says

    Hi Bill,

    Thanks for this useful tip. I use Gravity Forms at the moment, but could probably add something like this there too.

    There seems a small error in the second snippet, since it now checks for an empty array that also not contains “spam”, so perhaps you meant !empty( $debug ) in the first part?

    Cheers,
    Hans

    • Bill Erickson says

      You’re right, there is an error in the last snippet. That should be an OR statement, not an AND statement.

      The code should say “if the wpforms_logging option is empty, or if doesn’t contain spam, update the option to log only spam”.

Leave A Reply