Simple CAPTCHA with Cloudflare Turnstile

How can we help?

Search the documentation or ask the AI agent anything about the plugin.

Action reference

Updated September 13, 2026

The plugin fires several actions around rendering and verification. Some are meant to be hooked; a couple are meant to be fired by your own code when you render widget markup by hand.

cfturnstile_after_check

Fires after every verification, successful or not. Useful for your own logging or rate limiting.

add_action( 'cfturnstile_after_check', function ( $response, $results, $form_action = '' ) {
    if ( empty( $results['success'] ) ) {
        error_log( sprintf(
            'Turnstile failed on %s: %s',
            $form_action ? $form_action : 'unknown',
            isset( $results['error_code'] ) ? $results['error_code'] : 'no-code'
        ) );
    }
}, 10, 3 );

Parameters:

  • $response — the decoded response body from Cloudflare. On the failsafe path this is a minimal object carrying only success.
  • $results — an array with success, plus error_code on failure.
  • $form_action — the form identifier.

Give $form_action a default value in your callback. Registering for three arguments is safe, but the failsafe path supplies only two, and a required third parameter would fatal there.

cfturnstile_before_field and cfturnstile_after_field

Fire immediately before and after the widget markup, so you can wrap it in your own container.

  • cfturnstile_before_field receives the unique id suffix.
  • cfturnstile_after_field receives the unique id suffix and the submit button’s CSS selector, which is an empty string when submit-button disabling does not apply.

The id suffix is the tail of the widget’s DOM id, which is cf-turnstile followed by that suffix.

The plugin attaches several of its own callbacks to cfturnstile_after_field, so mind the priorities if ordering matters: the error message container runs at 5, submit-button disabling and the explicit render queue at 10, the spacing for always-on mode at 15, and admin context styles at 20.

cfturnstile_enqueue_scripts

Takes no arguments. This is one you fire rather than hook. Call it when you output widget markup by hand instead of going through the plugin’s render helper, so the Cloudflare API script and the plugin’s styles are enqueued:

do_action( 'cfturnstile_enqueue_scripts' );

cfturnstile_enqueue_scripts_custom

Takes no arguments. Fires at the end of the plugin’s own enqueue routine, which is where you register integration JavaScript that depends on the Turnstile script:

add_action( 'cfturnstile_enqueue_scripts_custom', function () {
    wp_enqueue_script(
        'my-turnstile-integration',
        plugins_url( '/js/my-integration.js', __FILE__ ),
        array( 'cfturnstile' ),
        '1.0',
        array( 'in_footer' => true )
    );
} );

cfturnstile_wp_login_failed

Takes no arguments. Fires after the WordPress login check fails, just before the error is returned. Useful for feeding your own rate limiting or intrusion logging.

cfturnstile-settings-section

Takes no arguments. Prints inside the settings form so an add-on can render its own rows. Any option your section renders must also be registered in the plugin’s settings allowlist — the save handler works from that list, so a field the UI shows but the allowlist does not include is wiped on every save.

Related

Was this article helpful?