blendbyte / livewire-honeypot
Honeypot + time-trap spam protection for Livewire 4 forms. No CAPTCHAs, no external requests.
Requires
- php: ^8.5
- laravel/framework: ^13.0
- livewire/livewire: ^4.0
Requires (Dev)
- larastan/larastan: ^3.0
- orchestra/testbench: ^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- pestphp/pest-plugin-livewire: ^4.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
livewire-honeypot
Honeypot and minimum-fill-time protection for Livewire forms, without CAPTCHAs or external requests. Requires PHP 8.5, Laravel 13, and Livewire 4.
Install
composer require blendbyte/livewire-honeypot
The service provider is registered automatically.
Protect a Livewire form
Add the trait to your component and validate the honeypot before processing the submission:
use Blendbyte\LivewireHoneypot\Traits\HasHoneypot; use Livewire\Component; class ContactForm extends Component { use HasHoneypot; public string $email = ''; public function submit(): void { $this->validateHoneypot(); $this->validate(['email' => 'required|email']); // Process the submission here. $this->reset('email'); $this->resetHoneypot(); } public function render() { return view('livewire.contact-form'); } }
In resources/views/livewire/contact-form.blade.php:
<form wire:submit="submit"> <x-honeypot /> <label for="email">Email</label> <input id="email" type="email" wire:model="email"> @error('email') <p>{{ $message }}</p> @enderror <button type="submit">Send</button> </form>
By default, the hidden bait must stay empty, submissions must wait 5 seconds, and forms expire after 1 hour. Honeypot errors appear beside the component; style .hp-error to match your form.
Keep the trait on the Livewire component, including when using a Livewire Form object. Call resetHoneypot() after a successful submission to refresh the form's protection.
Configuration
Most applications can use the defaults. To change the waiting time or enable detection logs:
HONEYPOT_MINIMUM_FILL_SECONDS=3 HONEYPOT_LOGGING=true
Set the minimum to 0 to disable the waiting period. For all options, publish the configuration file:
php artisan vendor:publish --tag=livewire-honeypot-config
Override settings for one component with honeypotConfig():
protected function honeypotConfig(): array { return ['minimum_fill_seconds' => 10]; }
For a single action, use $this->validateHoneypot(minimumSeconds: 2).
Custom bait bindings
Declare an empty bait property, such as public array $contact = ['trap' => ''];, and use the same path in the view and validation calls:
<x-honeypot wire:model="contact.trap" />
$this->validateHoneypotForModel('contact.trap'); // Validate and process the rest of the form. $this->resetHoneypotForModel('contact.trap');
This also works with form.trap on a Livewire form object. If you change field_name globally or through honeypotConfig(), declare a matching public property on the component. The default <x-honeypot /> binding follows that setting automatically.
Randomized HTML names
Set HONEYPOT_RANDOMIZE_FIELD_NAME=true and pass the generated name to the view:
<x-honeypot :field-name="$hp_field_name" />
This changes the HTML name while keeping the Livewire binding intact. Password-manager ignore hints are included, but autofill behavior varies by browser and extension.
Testing
Bypass honeypot checks in tests that focus on the rest of your form:
use Blendbyte\LivewireHoneypot\Services\HoneypotService; beforeEach(fn () => HoneypotService::fake()); afterEach(fn () => HoneypotService::resetFake());
To test the waiting period itself, mount the component and advance time before submitting:
$component = Livewire::test(ContactForm::class); $this->travel(5)->seconds(); $component->call('submit');
The timestamp and token are locked properties, so use time travel instead of setting them through Livewire.
For the package's own PHP and browser checks, see running the test suites.
More options
- Plain HTML forms: signed tokens and controller validation.
- Advanced options: CSP, responders, events, translations, and JS verification.
- Upgrading existing integrations: published views, custom bindings, and signed tokens.
Honeypots catch simple automation, not every bot. Keep normal validation, CSRF protection, and rate limiting on your forms.
Forked from ArvidDeJong/livewire-honeypot. Licensed under MIT.
Maintained by Blendbyte
Blendbyte builds cloud infrastructure, web apps, and developer tools.
We've been shipping software to production for 20+ years.
This package runs in our own stack, which is why we keep it maintained.
Issues and PRs get read. Good ones get merged.