Download the PHP package happenv-com/filament-turnstile without Composer
On this page you can find all versions of the php package happenv-com/filament-turnstile. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download happenv-com/filament-turnstile
More information about happenv-com/filament-turnstile
Files in happenv-com/filament-turnstile
Package filament-turnstile
Short Description Cloudflare Turnstile panel plugin for Filament v4 and v5 — register once, auto-protect login (and optionally registration / password reset).
License MIT
Homepage https://github.com/happenv-com/filament-turnstile
Informations about the package filament-turnstile
Filament Turnstile
Cloudflare Turnstile panel plugin for Filament v4 and v5. Register it once on a panel and login is protected automatically — optionally registration and password-reset request too. No form schema edits for the common case.
Based on muazzambuilds/filament-turnstile by Muazzam Builds.
Key features
- Login, registration and password reset — one panel plugin protects Filament's auth pages; each page is switched on or off on its own. See Panel plugin.
- Multi-factor authentication aware — Turnstile runs on the password step only, never again on the app code or passkey challenge.
- Custom auth pages — one trait per page (
Login,Register,RequestPasswordReset) adds Turnstile to your own subclasses, plus aTurnstileform field for any other Filament form. See Custom auth pages. - Testing helpers — Livewire test mixins (
assertTurnstileBlocks(),assertTurnstileAllows(),passTurnstile(), …) for Pest and PHPUnit, with Cloudflare's test keys answered locally, so tests never reach Cloudflare. See Testing your application. - Laravel 11, 12 and 13, Filament 4 and 5 — see Requirements.
- Translations — validation messages in 64 languages, every locale Filament ships. See Supported languages.
- Safe without keys — with no keys configured the widget is hidden and verification is skipped, so local apps still boot.
Requirements
| Package | Versions |
|---|---|
| PHP | 8.2 – 8.5 |
| Laravel | 11, 12, 13 |
| Filament | 4, 5 |
CI runs the test suite on PHP 8.3 – 8.5 with Laravel 12 and 13 and Filament 4 and 5. PHP 8.2 and Laravel 11 are allowed by composer.json but cannot be tested in CI (the test tooling needs PHP 8.3, and Composer refuses every Laravel 11 release because of security advisories).
Installation
Install the package via Composer:
Add your keys to .env:
Create a widget and get keys at dash.cloudflare.com → Turnstile.
Register the plugin in your panel provider — see Panel plugin below.
The widget's wrapper uses a few Tailwind classes. If your panel uses a custom theme, add the package's views to its CSS file so Tailwind generates them:
Configuration
Publish the config file (optional):
Optionally, publish the views:
Usage
Panel plugin (recommended)
Call ->plugin(...) after ->login() / ->registration() / ->passwordReset() so the plugin can swap the auth page classes:
Defaults: login is protected; registration and password-reset request are not.
Each page is toggled independently, so any combination works — e.g. registration and password reset only:
Login protection works with Filament multi-factor authentication (app codes, passkeys): Turnstile appears only on the password step, and the multi-factor challenge step has no widget and no second verification.
Widget options
Manual form field
For custom auth pages or any Filament form:
Disable auto-swap and extend or compose yourself:
Custom auth pages
Keep extending Filament's page and add the matching trait from Happenv\FilamentTurnstile\Concerns — it carries everything the packaged page does:
| Your page extends | Use trait |
|---|---|
Login |
InteractsWithTurnstileLogin |
Register |
InteractsWithTurnstileRegistration |
RequestPasswordReset |
InteractsWithTurnstilePasswordReset |
What each trait adds:
- Every trait gives the page a default form with the widget and resets the widget on any validation error.
InteractsWithTurnstileLoginalso resets the widget after a wrong password and skips it on the multi-factor challenge step (app codes, passkeys). The token was already verified on the password step, and Cloudflare accepts a token only once.InteractsWithTurnstileRegistrationalso keeps the token out of the data passed to user creation.InteractsWithTurnstilePasswordResetalso resets the widget after each request, so another one can be sent.
InteractsWithTurnstile is the shared base — use it directly only for forms other than these auth pages.
Register the page yourself and turn off the plugin's swap for it, otherwise the plugin replaces it with the packaged page:
Use the login trait (not the generic InteractsWithTurnstile) on login pages: it keeps Turnstile off the multi-factor challenge step.
Testing your application
Local and CI keys
Cloudflare test keys (any hostname, including localhost):
| Purpose | Site key | Secret key |
|---|---|---|
| Always passes | 1x00000000000000000000AA |
1x0000000000000000000000000000000AA |
| Always blocks | 2x00000000000000000000AB |
2x0000000000000000000000000000000AA |
| Token already spent | — | 3x0000000000000000000000000000000AA |
With a test site key the widget produces the dummy token XXXX.DUMMY.TOKEN.XXXX. The package answers the test secret keys itself, the same way Cloudflare does — verification never leaves the app, so it works offline and with Http::preventStrayRequests(). Production secret keys reject the dummy token.
If keys are missing, the widget is hidden and server validation is skipped so local apps without Turnstile still boot.
Livewire test helpers
The package adds Turnstile helpers to Livewire's test object (Livewire::test(...), or livewire(...) from pest-plugin-livewire), the same way Filament adds fillForm() — they work in Pest and PHPUnit alike. Each helper switches the app to the Cloudflare test keys above and fills the dummy token, so no request reaches Cloudflare.
Test the page your panel registers — the packaged one, or your own page using a trait:
| Helper | What it does |
|---|---|
assertTurnstileBlocks($method) |
Fails the token, calls $method, asserts a Turnstile error. |
assertTurnstileAllows($method) |
Passes the token, calls $method, asserts no Turnstile error. |
assertTurnstileActive() |
The form shows the widget and verifies its token on submit. |
assertTurnstileInactive() |
The form has no widget, or it is hidden — keys missing, plugin disabled, page not protected, or the multi-factor challenge step. |
passTurnstile() |
Only sets up a passing token — follow with your own call() and assertions. |
failTurnstile() |
Only sets up a failing token. |
assertTurnstileBlocks() and assertTurnstileAllows() first assert the widget is active, so they fail on a page Turnstile does not protect instead of passing silently. Every helper takes the schema name as its last argument (default form); the two call helpers take the method's arguments before it:
Use passTurnstile() to get past Turnstile in tests about something else — the full login with a multi-factor challenge, for example:
The helpers change the filament-turnstile.* keys in the config for the rest of that test.
Browser tests
The helpers above extend Livewire's test object; Pest's browser pages cannot be extended the same way. In a browser test, switch to the test keys yourself — Pest serves the app from the test process, so the config applies to the page. The real widget then solves itself; wait for its token before submitting:
The widget loads from challenges.cloudflare.com, so browser tests need network access.
Translations
Validation messages ship in every locale Filament ships — see Supported languages. The app locale picks the language.
To change a message or add a language, publish the files:
The widget itself follows the browser language; set ->language() or TURNSTILE_LANGUAGE to fix it.
Supported languages
| Language | Language | Language | Language |
|---|---|---|---|
Amharic am |
Persian fa |
Lithuanian lt |
Slovenian sl |
Arabic ar |
Finnish fi |
Mizo lus |
Albanian sq |
Azerbaijani az |
Filipino fil |
Latvian lv |
Serbian (Cyrillic) sr_Cyrl |
Bulgarian bg |
French fr |
Macedonian mk |
Serbian (Latin) sr_Latn |
Bengali bn |
Hebrew he |
Mongolian mn |
Swedish sv |
Bosnian bs |
Hindi hi |
Malay ms |
Swahili sw |
Catalan ca |
Croatian hr |
Burmese my |
Tajik tg |
Central Kurdish ckb |
Hungarian hu |
Norwegian Bokmål nb |
Thai th |
Czech cs |
Armenian hy |
Nepali ne |
Turkish tr |
Danish da |
Indonesian id |
Dutch nl |
Ukrainian uk |
German de |
Italian it |
Polish pl |
Urdu ur |
Greek el |
Japanese ja |
Portuguese pt |
Uzbek uz |
English en |
Georgian ka |
Portuguese (Brazil) pt_BR |
Vietnamese vi |
Spanish es |
Khmer km |
Romanian ro |
Chinese (Simplified) zh_CN |
Estonian et |
Korean ko |
Russian ru |
Chinese (Hong Kong) zh_HK |
Basque eu |
Kurdish ku |
Slovak sk |
Chinese (Traditional) zh_TW |
Development
The browser tests drive the real widget from challenges.cloudflare.com with Cloudflare's test keys, so they need network access.
Upgrading
Breaking changes and how to migrate are described in UPGRADING for every major version.
Changelog
See GitHub releases for what has changed recently.
Contributing
See CONTRIBUTING for details.
Security vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
- Happenv sp. z o.o.
- webard
- Muazzam Builds — author of the original muazzambuilds/filament-turnstile
- All contributors
License
The MIT License (MIT). See License File for more information.
All versions of filament-turnstile with dependencies
filament/filament Version ^4.0|^5.0
illuminate/contracts Version ^11.0|^12.0|^13.0
illuminate/http Version ^11.0|^12.0|^13.0
illuminate/support Version ^11.0|^12.0|^13.0
spatie/laravel-package-tools Version ^1.16