Skip to content

Bot Protection

Protect your forms from bots using Cloudflare Turnstile captcha.

Formlander integrates with Cloudflare Turnstile, a privacy-friendly CAPTCHA alternative, to protect forms from bot submissions.

Sign up and get your keys from the Cloudflare Turnstile dashboard:

  • Site Key (public) - Embedded in your HTML
  • Secret Key (private) - Stored in Formlander’s database
  1. Log into your Formlander dashboard
  2. Navigate to Settings → Captcha Profiles
  3. Click Create New Profile
  4. Enter a profile name (e.g., “Production Captcha”)
  5. Enter your Turnstile Site Key and Secret Key
  6. Save the profile

Note: Turnstile credentials are stored securely in the database and managed through the admin interface, not environment variables.

  1. Go to Forms in the admin dashboard
  2. Edit or create a form
  3. Select your Captcha Profile from the dropdown
  4. Save the form

Include the Turnstile widget in your form:

<form action="https://your-domain.com/forms/contact/submit?token=YOUR_TOKEN" method="post">
<!-- Your form fields -->
<label>
Name
<input type="text" name="name" required>
</label>
<label>
Email
<input type="email" name="email" required>
</label>
<label>
Message
<textarea name="message" required></textarea>
</label>
<!-- Cloudflare Turnstile widget -->
<div class="cf-turnstile" data-sitekey="YOUR_SITE_KEY"></div>
<button type="submit">Send</button>
</form>
<!-- Load Turnstile script -->
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>

Replace YOUR_SITE_KEY with your actual Turnstile Site Key.

Formlander automatically validates the Turnstile token server-side before accepting submissions. If validation fails:

{
"ok": false,
"error": "captcha validation failed"
}

Cloudflare offers three challenge modes:

ModeDescriptionUser Experience
ManagedShows CAPTCHA only when needed based on risk✅ Recommended - Minimal friction
Non-interactiveInvisible challenge runs in backgroundZero friction, but may not catch all bots
Always visibleTraditional CAPTCHA every timeMaximum security, more friction

Configure the mode in your Cloudflare Turnstile settings.

Formlander supports multiple Captcha Profiles, allowing you to:

  • Use different Turnstile keys for different domains
  • Have separate configurations for staging vs. production
  • Assign specific profiles to specific forms

Example setup:

  1. Profile: “Production Forms”

    • Site Key: 1x00000000000000000000AA
    • Assigned to: Contact Form, Newsletter Form
  2. Profile: “Staging Environment”

    • Site Key: 1x00000000000000000000BB
    • Assigned to: Test Forms

For single-page applications, use the Turnstile React component:

import { Turnstile } from '@marsidev/react-turnstile'
function ContactForm() {
const [token, setToken] = useState('')
const handleSubmit = async (e) => {
e.preventDefault()
const formData = new FormData(e.target)
formData.append('cf-turnstile-response', token)
const response = await fetch('https://your-domain.com/forms/contact/submit?token=YOUR_TOKEN', {
method: 'POST',
body: formData,
})
// Handle response...
}
return (
<form onSubmit={handleSubmit}>
<input name="name" required />
<input name="email" type="email" required />
<textarea name="message" required />
<Turnstile
siteKey="YOUR_SITE_KEY"
onSuccess={setToken}
/>
<button type="submit">Send</button>
</form>
)
}

Formlander logs all failed captcha attempts in structured logs under storage/logs/:

{
"level": "warn",
"ts": "2025-11-07T14:30:00Z",
"msg": "submission blocked: captcha validation failed",
"form_slug": "contact",
"ip_hash": "abc123...",
"reason": "captcha_failed"
}

Monitor these logs to:

  • Identify bot attack patterns
  • Adjust Turnstile sensitivity if needed
  • Detect false positives
  1. Start with Managed Mode - Balances security and user experience
  2. Use multi-domain profiles - Separate production from staging/testing
  3. Monitor false positives - Watch for legitimate users getting blocked
  4. Combine with rate limiting - Captcha alone won’t stop all abuse (see Abuse Prevention)
  5. Test thoroughly - Verify captcha works before deploying
  • ✅ Verify Site Key matches your Cloudflare dashboard
  • ✅ Confirm Secret Key is correctly saved in Formlander
  • ✅ Check that the captcha profile is assigned to the form
  • ✅ Ensure Turnstile script is loaded (<script src="...">)
  • ✅ Check browser console for JavaScript errors
  • ✅ Verify Site Key is correct in your HTML
  • ✅ Ensure Turnstile script is loaded before form renders
  • ✅ Check for CSP (Content Security Policy) blocking Cloudflare
  • Switch from “Always visible” to “Managed” mode
  • Review Cloudflare Turnstile settings for sensitivity
  • Consider allowing users to retry failed challenges