hCaptcha blocks automated contact-form submissions. Outside Laravel's local environment, PagibleAI shows the challenge when the sitekey is set and validates it on the server when the secret is set, so always configure both keys together.
Configure hCaptcha for PagibleAI
Create an hCaptcha account
Open the hCaptcha plans, choose an account for your traffic and support needs, and verify the email address. For a production site, use an organization-owned account rather than a personal login.
Register the hostnames
- Open the hCaptcha site settings.
- Enter a name for the PagibleAI site.
- Add every production and staging hostname that will show the form.
- Save the site with the difficulty and security settings you need.
Enter hostnames without paths. Keep test and production configurations separate when they have different access rules.
Get the sitekey and secret
Copy the public sitekey from Sites and the private siteverify secret from account settings. The sitekey appears in page markup; the secret must stay on the server. Store the secret in your deployment secret manager and rotate it if it leaks.
Add the keys to PagibleAI
Add both values to the application environment. The PagibleAI theme installer connects them to Laravel's services.hcaptcha configuration:
HCAPTCHA_SITEKEY="..."
HCAPTCHA_SECRET="..."
Run the command below after changing either value. Then restart Octane, queue workers and other long-running PHP processes.
Set both values or none. With only the secret, the form doesn't show the challenge but the server still requires a valid response, so every submission fails. With only the sitekey, visitors see the challenge but the server never verifies it.
php artisan config:clear
Test the contact form
Test on staging or production; the default contact form skips hCaptcha when Laravel runs in the local environment.
- Open the form and check that the challenge loads.
- Submit without a valid challenge; validation should reject the request.
- Complete the challenge and send a harmless test message.
- Check that the message follows the site's normal delivery path.
The contact element lets editors choose the mandatory and optional form fields (name, company, telephone, e-mail, subject or own field names); name and e-mail are mandatory by default. The form fetches its CSRF token from cmsapi/csrf only when a visitor submits it, so cached pages keep working. Submissions are limited by the cms-contact rate limiter to two per minute per IP address, so send test messages at least 30 seconds apart.
Troubleshooting
Why is the widget missing locally?
The default PagibleAI contact form skips hCaptcha in Laravel's local environment. Test on a staging hostname in another environment.
Why does every submission fail without a visible challenge?
HCAPTCHA_SECRET is set but HCAPTCHA_SITEKEY is empty. The server then requires a captcha response the form never shows. Set the sitekey too, or remove both values.
Why does hCaptcha reject the sitekey?
Check that HCAPTCHA_SITEKEY belongs to this site and that the current hostname is registered. Clear the configuration cache after changing it.
Why does hCaptcha report a sitekey-secret mismatch?
The sitekey and HCAPTCHA_SECRET must belong to the same hCaptcha account and site configuration.
Why does the form return HTTP 429?
The cms-contact rate limiter allows two submissions per minute per IP address. Wait a minute before testing again.
Why does the browser block the challenge?
Check your Content Security Policy. Custom policies must allow the hCaptcha script, frame, style and connection hosts used by the default theme.
The default frame-src is https://hcaptcha.com https://*.hcaptcha.com https://www.openstreetmap.org; the OpenStreetMap host is used by the map element. If you override CMS_CSP_FRAME_SRC, keep both hCaptcha hosts and also include https://www.openstreetmap.org when your pages use the map element.
What if the secret was exposed?
Generate a new siteverify secret, deploy it as HCAPTCHA_SECRET, clear the configuration cache and restart workers. Remove the old value from logs and source history.