Installation
composer require marcogermani87/filament-captcha
Publish the config (optional):
php artisan vendor:publish --provider="MarcoGermani87\FilamentCaptcha\FilamentCaptchaServiceProvider"
Register the Plugin
Add to your app/Providers/Filament/AdminPanelProvider.php:
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
\MarcoGermani87\FilamentCaptcha\FilamentCaptchaPlugin::make(),
]);
}
First Use Case Add a CAPTCHA field to a Filament form:
use MarcoGermani87\FilamentCaptcha\Fields\Captcha;
public static function form(Form $form): Form
{
return $form
->schema([
// ... other fields
Captcha::make('captcha')
->label('Verify you are human')
->required(),
]);
}
Basic CAPTCHA Integration
Captcha::make('captcha')
->label('Human verification')
->required()
->rules(['required', 'captcha']) // Custom validation rules
Customizing CAPTCHA Appearance
Captcha::make('captcha')
->fontPath(public_path('fonts/custom-font.ttf'))
->width(200)
->height(80)
->length(6)
->backgroundColor('#f5f5f5')
->textColor('#333')
Dynamic CAPTCHA Refresh Use JavaScript to refresh the CAPTCHA on demand:
document.querySelector('#refresh-captcha').addEventListener('click', function() {
fetch('/filament-captcha/refresh', {
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Accept': 'application/json',
},
})
.then(response => response.json())
.then(data => {
document.querySelector('#captcha-image').src = data.image;
});
});
Conditional CAPTCHA Show CAPTCHA only for specific user roles or actions:
public static function form(Form $form): Form
{
return $form
->schema([
// ... other fields
Captcha::make('captcha')
->visible(fn (User $record) => $record->isAdmin()),
]);
}
Validation in Custom Rules
Extend validation logic in your form's save method:
public function save(Form $form): void
{
$form->validate([
'captcha' => ['required', 'captcha'],
]);
// ... rest of the logic
}
Form and Table components.Captcha field to add custom validation logic:
Captcha::make('captcha')
->rules(['required', 'captcha', 'custom_rule'])
->customRule('custom_rule', function ($attribute, $value, $fail) {
if ($value !== 'expected_value') {
$fail('Custom validation failed.');
}
});
// resources/lang/en/forms.php
{
"fields": {
"captcha": {
"label": "Verify you are human",
"messages": {
"required": "Please verify you are human.",
"captcha": "The CAPTCHA code is incorrect."
}
}
}
}
CSRF Token Conflicts Ensure your CAPTCHA form includes the correct CSRF token. If using AJAX, include it in the request headers or form data.
Image Path Issues If CAPTCHA images fail to load, verify:
storage_path('app/captcha') directory is writable.filament-captcha config paths are correctly set in config/filament-captcha.php.Validation Rule Mismatch
The default validation rule is captcha. If you customize the field name, ensure the validation rule matches:
// Incorrect (if field name is 'human_verification')
'rules' => ['required', 'captcha'],
// Correct
'rules' => ['required', 'human_verification'], // or custom rule
Caching Issues Clear cached views and config if CAPTCHA changes aren't reflecting:
php artisan view:clear
php artisan config:clear
Check Logs Enable debug mode to log CAPTCHA generation issues:
// config/filament-captcha.php
'debug' => env('CAPTCHA_DEBUG', false),
Verify Image Generation Manually trigger CAPTCHA generation to check for errors:
use MarcoGermani87\FilamentCaptcha\Facades\FilamentCaptcha;
$captcha = FilamentCaptcha::generate();
dd($captcha); // Check if image and code are generated correctly
Test Validation Test CAPTCHA validation separately:
use Illuminate\Support\Facades\Validator;
$validator = Validator::make(['captcha' => 'test123'], ['captcha' => 'required|captcha']);
dd($validator->fails()); // Should return true if invalid
Custom CAPTCHA Providers Extend the package by creating a custom CAPTCHA provider:
namespace App\Providers;
use MarcoGermani87\FilamentCaptcha\Contracts\CaptchaProvider;
use Gregwar\Captcha\CaptchaBuilder;
class CustomCaptchaProvider implements CaptchaProvider
{
public function build(): CaptchaBuilder
{
return CaptchaBuilder::create()
->build();
}
}
Register it in the config:
// config/filament-captcha.php
'provider' => \App\Providers\CustomCaptchaProvider::class,
Hooks and Events Listen for CAPTCHA generation events to log or modify behavior:
use MarcoGermani87\FilamentCaptcha\Events\CaptchaGenerated;
event(new CaptchaGenerated($captchaCode, $captchaImage));
Custom Field Attributes
Extend the Captcha field class to add custom attributes:
namespace App\Filament\Fields;
use MarcoGermani87\FilamentCaptcha\Fields\Captcha as BaseCaptcha;
class CustomCaptcha extends BaseCaptcha
{
protected string $template = 'filament-captcha::custom-field';
public function customize(): void
{
$this->extraAttributes(['class' => 'custom-captcha']);
}
}
Storage Path
Ensure the storage_path('app/captcha') directory exists and is writable. Create it manually if needed:
mkdir -p storage/app/captcha
chmod -R 775 storage/app/captcha
Font Paths If using custom fonts, ensure the path is absolute and accessible:
// Incorrect (relative path)
->fontPath('fonts/custom-font.ttf')
// Correct (absolute path)
->fontPath(public_path('fonts/custom-font.ttf'))
Environment Variables
Override default settings via .env:
CAPTCHA_LENGTH=6
CAPTCHA_WIDTH=200
CAPTCHA_HEIGHT=80
CAPTCHA_BACKGROUND_COLOR=#f5f5f5
CAPTCHA_TEXT_COLOR=#333
How can I help you explore Laravel packages today?