No CAPTCHA reCAPTCHA Integration with WordPress

    Collins Agbonghama

    A few weeks ago, the Google security team announced a new version of the popular reCAPTCHA system used by millions of websites in combating spam.

    For years, reCAPTCHA has prompted users to confirm they aren’t robots by asking them to read distorted text to be entered into a box, like this:

    The Old reCAPTCHA

    A lot of people griped and faulted the old reCAPTCHA system for many reasons. The distorted text it produces is difficult to recognize and bots get past the test better than humans do.

    The new CAPTCHA is easy and convenient. All you need to do is click on a checkbox and you’re done. It’s also pretty effective in combating spam.

    The New "No CAPTCHA"

    Previously on SitePoint, we wrote a series on integrating the old reCAPTCHA to the following WordPress forms:

    In this article, we will learn how to integrate the new No CAPTCHA reCAPTCHA with a custom form and WordPress.

    reCAPTCHA Form Integration

    Let’s go over the process on how to integrate reCAPTCHA with a web form.

    First off, head over to reCAPTCHA to grab your site and secret key.

    Displaying the CAPTCHA

    Include the following to the header section of the web page: <script src="" async defer></script>.

    Add <div class="g-recaptcha" data-sitekey="your_site_key"></div> to wherever you want to output the CAPTCHA where your_site_key is your domain site/public key.

    More information on configuring the display of the CAPTCHA widget can be found here.

    Verifying the User’s Response

    To verify the user response (check if the user passed or failed the CAPTCHA test), send a GET request to the URL below using either cURL, Guzzle, WordPress HTTP API or any HTTP client.


    your_secret: Secret (private) key.
    response_string: The user response token (retrieved via PHP by $_POST['g-recaptcha-response']) ).
    user_ip_address: The user IP address albeit optional. ($_SERVER["REMOTE_ADDR"]).

    If the request was successfully sent, the response will be a JSON object similar to the one below.

      "success": true|false

    Decode the response using json_decode() and grab success property $response['success'] which returns true if the user passes the test, or false otherwise.

    More information on verifying the user response can be found here.

    reCAPTCHA WordPress Integration

    Having learned how the new No CAPTCHA reCAPTCHA can be integrated with a form, let’s also see how it can be integrated with WordPress.

    The first step is to include the plugin file header:

    Plugin Name: No CAPTCHA reCAPTCHA
    Plugin URI:
    Description: Protect WordPress login, registration and comment form from spam with the new No CAPTCHA reCAPTCHA
    Version: 1.0
    Author: Agbonghama Collins
    Author URI:
    License: GPL2

    Enqueue the reCAPTCHA script to WordPress header section.

    // add the header script to login/registration page header
    add_action( 'login_enqueue_scripts', 'header_script' );
    // add CAPTCHA header script to WordPress header
    add_action( 'wp_head', 'header_script' );
    /** reCAPTCHA header script */
    function header_script() {
    echo '<script src="" async defer></script>';

    Next we use display_captcha() and the captcha_verification() wrapper function for displaying the CAPTCHA widget and verifying the user response.

    Note: change *your_site_key* and *your_secret* in the code below to your site (public) key and secret (private) key respectively.

    /** Output the reCAPTCHA form field. */
    function display_captcha() {
    	echo '<div class="g-recaptcha" data-sitekey="your_site_key"></div>';
     * Send a GET request to verify CAPTCHA challenge
     * @return bool
    function captcha_verification() {
    	$response = isset( $_POST['g-recaptcha-response'] ) ? esc_attr( $_POST['g-recaptcha-response'] ) : '';
    	$remote_ip = $_SERVER["REMOTE_ADDR"];
    	// make a GET request to the Google reCAPTCHA Server
    	$request = wp_remote_get(
    		'' . $response . '&remoteip=' . $remote_ip
    	// get the request response body
    	$response_body = wp_remote_retrieve_body( $request );
    	$result = json_decode( $response_body, true );
    	return $result['success'];

    We’ve now defined the base functionality of the plugin, up next is integrating the CAPTCHA with login, registration and comment forms.

    Login Form

    Include the CAPTCHA widget to the login form by hooking the function display_captcha() to the login_form Action.

    // adds the CAPTCHA to the login form
    add_action( 'login_form', array( __CLASS__, 'display_captcha' ) );

    The validate_login_captcha() function will validate and ensure the CAPTCHA checkbox isn’t left unchecked and that the test is passed.

    // authenticate the CAPTCHA answer
    add_action( 'wp_authenticate_user', 'validate_captcha', 10, 2 );
     * Verify the CAPTCHA answer
     * @param $user string login username
     * @param $password string login password
     * @return WP_Error|WP_user
    function validate_captcha( $user, $password ) {
    	if ( isset( $_POST['g-recaptcha-response'] ) && !captcha_verification() ) {
    		return new WP_Error( 'empty_captcha', '<strong>ERROR</strong>: Please retry CAPTCHA' );
    	return $user;

    Registration Form

    Include the CAPTCHA widget to the registration form by hooking the function display_captcha() to the register_form Action.

    // adds the CAPTCHA to the registration form
    add_action( 'register_form', 'display_captcha' );

    Validate the CAPTCHA test in the registration form with the validate_captcha_registration_field() function hooked to registration_errors.

    // authenticate the CAPTCHA answer
    add_action( 'registration_errors', 'validate_captcha_registration_field', 10, 3 );
     * Verify the captcha answer
     * @param $user string login username
     * @param $password string login password
     * @return WP_Error|WP_user
    function validate_captcha_registration_field( $errors, $sanitized_user_login, $user_email ) {
    	if ( isset( $_POST['g-recaptcha-response'] ) && !captcha_verification() ) {
    		$errors->add( 'failed_verification', '<strong>ERROR</strong>: Please retry CAPTCHA' );
    	return $errors;

    Comment Form

    First, create a global variable that will hold the status of the CAPTCHA test. That is, when a user fails the challenge, it is set to ‘failed’ and empty otherwise.

    global $captcha_error;

    Include the CAPTCHA widget to the comment form by hooking the display_captcha() function to the comment_form Action.

    // add the CAPTCHA to the comment form
    add_action( 'comment_form', 'display_captcha' );

    The filter preprocess_comment calls the validate_captcha_comment_field() function to ensure the CAPTCHA field isn’t left empty and also that the answer is correct.

    // authenticate the captcha answer
    add_filter( 'preprocess_comment', 'validate_captcha_comment_field');
     * Verify the captcha answer
     * @param $commentdata object comment object
     * @return object
    function validate_captcha_comment_field( $commentdata ) {
    	global $captcha_error;
    	if ( isset( $_POST['g-recaptcha-response'] ) && ! (captcha_verification()) ) {
    		$captcha_error = 'failed';
    	return $commentdata;

    The filter comment_post_redirect calls redirect_fail_captcha_comment() to delete comments detected as spam and also adds some query parameters to the comment redirection URL.

    add_filter( 'comment_post_redirect', 'redirect_fail_captcha_comment', 10, 2 );
     * Delete spam comments
     * Add query string to the comment redirect location
     * @param $location string location to redirect to after comment
     * @param $comment object comment object
     * @return string
    function redirect_fail_captcha_comment( $location, $comment ) {
    	global $captcha_error;
    	if ( ! empty( $captcha_error ) ) {
    		// delete the failed captcha comment
    		wp_delete_comment( absint( $comment->comment_ID ) );
    		// add failed query string for @parent::display_captcha to display error message
    		$location = add_query_arg( 'captcha', 'failed', $location );
    	return $location;

    Voila! We’re done coding the plugin.


    In this article, we learned how to protect web forms against spam using the new No CAPTCHA reCAPTCHA and finally, integrated it with the WordPress login, registration and comment forms.

    If you’d like to integrate the new reCAPTCHA widget with your WordPress powered site, the plugin is available at the WordPress plugin directory.

    Until I come your way again, happy coding!