Cloudflare Turnstile captcha for the form submission flow. Usually included inside Form Submit. The widget stays hidden until submit begins, then gates the API call.
Namespace
prc-block/form-captcha
Category
forms
Block inserter example
block.json includes an empty example object so the inserter uses default attributes.
Supports
| Feature | Value |
|---|---|
| Spacing (margin) | true |
| Interactivity | true |
| HTML | false |
Attributes
None. State comes from the parent form interactivity context.
Parent / ancestor
No explicit constraint in block.json. Designed to run inside prc-block/form (typically nested under Form Submit).
Usage
- Prefer the Form Submit template, which already includes this block.
- No inspector config — uses
PRC_PLATFORM_TURNSTILE_SITE_KEY. - On submit, the form reveals captcha; after success, submission continues.
Requirements
PRC_PLATFORM_TURNSTILE_SITE_KEYmust be defined.- The Turnstile script is registered and enqueued by the block’s PHP class.
Block markup example
<!-- wp:prc-block/form-captcha /-->
PHP rendering
Fully server-rendered in src/form-captcha/class-form-captcha.php.
- Registers Turnstile (
explicitrender +onloadTurnstileCallback). - Outputs a container with
data-wp-interactive="prc-block/form-captcha",targetNamespacepointing atprc-block/form,data-wp-watch="callbacks.onInit", anddata-wp-bind--hiddenon captcha visibility. - Inner element carries
data-sitekey.
Frontend interactivity
Store namespace: prc-block/form-captcha
Callbacks
| Callback | Description |
|---|---|
onInit | Watches parent captchaHidden. When false, calls turnstile.render(). On success, sets captchaToken and captchaPassed on the parent form context so onCaptchaPassing can submit. |
Interaction flow
- User clicks submit.
- Form
onSubmitsetscaptchaHidden = false. - Captcha
onInitrenders Turnstile. - User completes the challenge.
- Parent gets
captchaPassed = true. - Form
onCaptchaPassingrunssendSubmission.
Turnstile client errors
view.js registers an error-callback so recoverable Cloudflare errors can retry without throwing (for example code 300031).
| Outcome | Behavior |
|---|---|
| Recoverable error | May retry; widget stays mounted |
Non-retryable (NON_RETRYABLE_TURNSTILE_CODES, e.g. invalid site key) | turnstile-error on parent form context; submission blocked |
| Repeated failures | Widget removed via turnstile.remove(); captcha state resets |
User-facing copy: getTurnstileErrorMessage(). See Cloudflare Turnstile client error codes.
Related
- Form
- Form Submit
- Architecture — public form security layers