Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Statamic Captcha Laravel Package

aryehraber/statamic-captcha

An addon for Statamic that adds CAPTCHA protection to forms, helping block spam and automated submissions. It offers simple configuration and server-side validation, making it easy to secure contact and other Statamic forms.

View on GitHub
Deep Wiki
Context7

Getting Started

  • composer require aryehraber/statamic-captcha, then publish the config: php artisan vendor:publish --tag=statamic-captcha-config (fall back to --provider="AryehRaber\Captcha\ServiceProvider" if the tag misses). You get config/statamic/captcha.php, which is the single source of truth for the default provider, per-provider credentials, render attributes, and verify URLs.

  • Set the provider and keys in .env rather than editing config: the file maps a provider key to a providers array (hcaptcha, recaptcha, recaptcha_v3, turnstile, and as of v1.18.0 fcaptcha). Copy the exact env var names out of the published stub — new providers get their own key/secret pair, so don't assume FCAPTCHA_KEY/FCAPTCHA_SECRET without checking.

  • First use case: open the template for one Statamic form (resources/views/forms/contact.antlers.html or whatever form:create renders) and drop the tag inside the form:

    {{ form:create in="contact" }}
        <input type="email" name="email">
        {{ captcha }}
        <button type="submit">Send</button>
    {{ /form:create }}
    

    Submit it. Verification happens through Statamic's form submission lifecycle, so a failure surfaces in the normal error bag — render it with {{ errors:captcha }} next to the tag.

  • Where to look first when something misbehaves: config/statamic/captcha.php (provider + verify URL), the addon's src/ provider classes (how each provider posts the token and parses the response), then the published views if you need to control markup.

Implementation Patterns

  • One provider, swapped by env. The tag markup is provider-agnostic, so keep {{ captcha }} in templates and switch CAPTCHA_PROVIDER per environment. Use the providers' documented always-pass test keys in local/staging rather than conditioning the tag out — conditional rendering is what causes "works on my machine, fails in prod" bugs.
  • Partial it. Wrap the tag in resources/views/partials/captcha.antlers.html so you have one place to add theme, lang, size, color, custom id/class, and your own fallback copy. Every form then includes the partial instead of repeating attributes.
  • Invisible/reCAPTCHA v3 flows rely on the tag emitting the hidden token field and the client script. Don't hand-roll the hidden input for these; if you must post to your own controller, reuse the package's validation rule/verification path rather than re-implementing the siteverify HTTP call.
  • User-facing forms beyond form:create (registration, password reset, contact-form-in-a-Blade-view): drop the same tag into the Antlers user form templates and confirm the submission event actually triggers verification — the integration point is Statamic's form events, so anything that bypasses those events bypasses the captcha.
  • Custom controllers / API endpoints. The tag layer is Statamic-only; for JSON endpoints call the provider verify endpoint yourself (via Http:: with the configured verify_url) and validate the returned success flag plus hostname/action for v3.
  • Testing. In phpunit.xml set the captcha env to a test-key configuration, and Http::fake() the verify URL with a canned success/failure body so submission tests are deterministic and CI never calls a third party.
  • Error UX. Show a human sentence, not the raw provider error. Keep a {{ if errors:captcha }} block adjacent to the widget and scroll/focus it on failure.

Gotchas and Tips

  • Leaving the tag out of a template fails closed and confusingly. The token field is absent, verification fails, and the user sees an error for a field that isn't on screen. Grep every form:create when rolling this out.
  • Config cache. After adding or switching providers (including the new fcaptcha block in v1.18.0), run php artisan config:clear. A stale cached config with no fcaptcha entry produces a null secret and a generic verification failure.
  • Re-publish vs merge on upgrade. v1.18.0 is additive — a new provider PR from a first-time contributor, no breaking changes — but published configs don't auto-update. Diff your config/statamic/captcha.php against the package stub and merge the new provider block by hand; don't blindly re-publish over your customisations.
  • Multiple widgets on one page. Give each {{ captcha }} a unique id; duplicate DOM ids break the provider scripts, and some providers only initialise the first element they find.
  • Score thresholds. reCAPTCHA v3 returns a score, not a boolean; false positives on legitimate users usually mean the threshold is too high in config, not that the integration is broken. Log the score during rollout.
  • Verify URL overrides exist for a reason. Regional blocking, corporate proxies, and self-hosted/compatible endpoints are handled through the per-provider verify_url rather than code changes — that's also the lever if you need to point at an alternate host.
  • CSP. hCaptcha, reCAPTCHA, Turnstile, and FCaptcha each load a script and an iframe from their own domain. Add script-src and frame-src entries for whichever provider you enable, or the widget silently fails to render.
  • Extension point. The providers array is the abstraction: a new provider (as with FCaptcha in v1.18.0) is config keys plus a verify call. If you need a service that isn't supported, model it on the closest existing provider's config shape rather than forking the package.
  • Don't treat it as complete spam protection. Captchas cut naive bot volume; pair with Statamic's honeypot/spam keywords and rate limiting for anything publicly exposed.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console