captchaapi/laravel
Official Laravel SDK for captchaapi.eu (EU-hosted, GDPR-friendly proof-of-work CAPTCHA). Includes Blade widget/component, server-side verification + validation rule, and optional Livewire 4 support. PHP 8.2+, Laravel 12/13.
Installation Add the package via Composer:
composer require captchaapi/laravel
Publish the config:
php artisan vendor:publish --tag=captchaapi-config
Set credentials in .env:
CAPTCHAAPI_SITE_KEY=pk_live_...
CAPTCHAAPI_SECRET_KEY=sk_live_...
First Use Case: Basic Form Protection
<head>:
<x-captchaapi::widget />
data-captcha:
<form method="POST" data-captcha>
@csrf
<!-- form fields -->
</form>
$request->validate([
'captchaapi_response' => ['required', new \Captchaapi\Laravel\Rules\ValidCaptcha],
]);
WithCaptcha in Livewire components for seamless validation:
use Captchaapi\Laravel\Concerns\WithCaptcha;
class MyComponent extends Component {
use WithCaptcha;
public function submit() {
$this->validateWithCaptcha(['field' => 'required']);
// Proceed...
}
}
<x-captchaapi::livewire-form> in Blade:
<x-captchaapi::livewire-form action="submit">
<input wire:model="email">
<button>Submit</button>
</x-captchaapi::livewire-form>
ValidCaptcha rule or alias 'captcha':
$request->validate([
'response' => ['required', 'captcha'], // Alias
]);
validateWithCaptcha() for concise validation:
$this->validateWithCaptcha(['email' => 'required']);
<form data-captcha>
<div data-captcha-status></div>
<!-- Form fields -->
</form>
[data-captcha-status][data-captcha-state="ready"] {
color: #059669;
}
.env for testing/staging:
CAPTCHAAPI_ENABLED=false
\Captchaapi\Laravel\Facades\Captchaapi::disable();
Secret Key Exposure
CAPTCHAAPI_SECRET_KEY in client-side code. The package ensures server-side-only usage via the ValidCaptcha rule.Livewire Double Validation
FakeCaptchaapi::enforceSingleUse() in tests to simulate this:
FakeCaptchaapi::enable()->enforceSingleUse();
Status Element Dependencies
data-captcha-status) requires the widget script. Omitting it runs silently.Rate Limiting
rate_limited states may indicate bot attacks. Monitor logs for CAPTCHAAPI_DEBUG=true.CAPTCHAAPI_DEBUG=true
site_key).fail_open Behavior:
true (allow submissions if the server fails). Set to false for sensitive actions (e.g., logins).CAPTCHAAPI_FAIL_OPEN=false
<html lang>. Force a locale via:CAPTCHAAPI_LOCALE=en
CAPTCHAAPI_PRELOAD=eager triggers CAPTCHA on page load (rarely needed).@error('captchaapi_response')
<p class="custom-error">{{ $message }}</p>
@enderror
CAPTCHAAPI_BASE_URL=https://staging.captchaapi.eu
FakeCaptchaapi to bypass real API calls:
FakeCaptchaapi::enable(); // Allows any response
FakeCaptchaapi::disable(); // Re-enables real validation
livewire-form wrapper uses data-captcha-mode="event" for Livewire’s wire:submit compatibility.captchaapi_response; avoid manual inclusion to prevent conflicts.CAPTCHAAPI_PRELOAD=lazy delays widget initialization until form interaction.
```markdown
---
How can I help you explore Laravel packages today?