This is a simple way to implement hCaptcha with Livewire component.
NOTE: please read this carefully, and adjust variable names, etc to your use case
Before using this implementation, add their JS library first on your page
<script src="https://js.hcaptcha.com/1/api.js?hl=en" async defer></script>
create a blade component (named anything. mine is: captcha.blade.php), and paste this:
(PLEASE READ ALL THE TODO!)
hcaptcha.blade.php
@props(['fieldName' => '', 'helperText' => ''])
<div
x-data="{}"
x-init="hcaptcha.render('h-captcha-{{$fieldName}}', {sitekey: 'TODO: add hCaptcha site key', callback: (e) => @this.set('{{$fieldName}}', e)})"
class="space-y-2">
<span class="text-sm font-medium leading-4 text-gray-700">
CAPTCHA (anti-bot)
<sup class="font-medium text-danger-700">*</sup>
</span>
<div wire:ignore id="h-captcha-{{$fieldName}}"></div>
<!-- TODO: add your own input error handler -->
<x-input-error :for="$fieldName"/>
<p class="text-sm text-gray-600">{{$helperText}}</p>
</div>
If you don't have an error handler component, you can use this:
input-error.blade.php
@props(['for'])
@error($for)
<p {{ $attributes->merge(['class' => 'text-sm text-red-600']) }}>{{ $message }}</p>
@enderror
Final step is to add the validator. create one via php artisan make:rule HcaptchaValidator
, then fill it with this
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
$captchaResp = Http::asForm()->post('https://hcaptcha.com/siteverify', [
'response' => $value,
'secret' => env('HCAPTCHA_SECRET')
])->object();
return $captchaResp->success;
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'error message here';
}
Paste the component on your Livewire component... :)
Replace fieldName to the variable on your livewire's component php file
livewire/any-component.blade.php
{{-- ...any field you have --}}
<x-captcha fieldName="fieldName" />
then on the method, you want to check if the token are valid and is not empty
public function someFunction(){
$this->validate([ 'fieldName' => ['required', new HcaptchaValidator()] ])
}
Your livewire component should now be protected with hCaptcha