Cloudflare Turnstile
Add Cloudflare Turnstile to XPAC Forms and check each submission on your server.
Cloudflare Turnstile adds Cloudflare's bot check to a form you protect. Most visitors pass without doing anything; some are asked to click. Your server then confirms the result with Cloudflare before it accepts the submission. Install and activate XPAC Forms first.
Connect Cloudflare Turnstile
In the Cloudflare dashboard, open Turnstile and choose Add widget. Add every domain that shows a protected form, pick a widget mode, and create it.
Paste both under XPAC → Integrations → Cloudflare Turnstile and save.
Click Test connection. It checks the secret key with Cloudflare. It can't check the site key, so submit a protected form once as well.
Admins can see both keys on this screen. It also sets the widget's look:
- Theme: Auto, Light or Dark.
- Size: Normal or Compact.
- Appearance mode: Always, or Interaction only, which shows the widget only when the visitor has to click. No effect on Invisible widgets.
On staging you can use Cloudflare's test keys. Test connection names them without calling Cloudflare, and they work on any domain. Save your real keys before going live.
Add it to a form
Edit the form, open Anti-spam protection and turn on Cloudflare Turnstile. If a key is missing, the editor warns that every submission is refused.
The widget appears just above the Submit button. To place it elsewhere, add the Cloudflare Turnstile block. The block only sets the position: while the toggle is off it does nothing and offers Turn on.
Cloudflare's script loads only on pages with a protected form, and it contacts
Cloudflare from the visitor's browser. Cover it in your privacy notice, and allow
challenges.cloudflare.com in your consent tool and content security policy.
When a submission is blocked
Turnstile only checks submissions. It doesn't send them anywhere, so it never appears on the Deliveries screen. It runs before Honeypot, reCAPTCHA and Akismet, so a bot it stops costs no Akismet check.
In the visitor's browser:
- If the check fails or expires, the visitor sees an error and can submit again.
- If an interactive check isn't finished after about 28 seconds, the visitor sees "Complete the spam check, then submit again." The check stays open.
- If
challenges.cloudflare.comis blocked, after about 4 seconds the visitor sees "The spam check could not load. Allow challenges.cloudflare.com or try another browser." Nothing is sent. - If the site key is wrong or the domain isn't in the widget's hostname list, the visitor is told the form isn't set up correctly. Admins see a notice naming the problem until the Turnstile settings are saved again or a day passes.
On your server, the submission is accepted only when Cloudflare confirms the check was solved on this site's own domain. If Cloudflare doesn't reply in 5 seconds or is busy, the server asks once more. Refused submissions go to the Spam view when Keep submissions marked as spam is on, and send no email or integration.
Accepted submissions show Verified and the time of the check in the Turnstile column.
A site that answers on more than one domain, such as with and without www, has
to list the others with the filter below, or their submissions are refused.
For developers
add_filter('xpac_cloudflare_turnstile_allowed_hostnames', function ($hosts) {
$hosts[] = 'www.example.com';
return $hosts;
});| Hook | Use |
|---|---|
xpac_cloudflare_turnstile_allowed_hostnames | Domains a check may come from. Default: the site's home and WordPress addresses. |
xpac_cloudflare_turnstile_request_timeout | Seconds to wait for Cloudflare. Default 5, from 1 to 10. |
Return false from xpac_forms_enable_verification for the provider
cloudflare-captcha to skip the check. Forms Auto Submit does this, because a
link has no browser to show the widget in.
Setup problems, including widget errors a visitor's browser reports on this site's
own domains, are written to the PHP error log with the prefix
XPAC cloudflare-turnstile:.
Settings are saved in the xpac option under keys starting cf_turnstile_. Each
form's toggle is under cloudflareCaptcha in its form_settings meta. The block
is xp/form-field-cloudflare-turnstile. The token is posted as
cloudflareCAPTCHA and never stored.