All resources
Spam protection

How to Stop Contact Form Spam Without reCAPTCHA

Kill contact form spam without annoying reCAPTCHA puzzles. How honeypots, rate limiting, and Cloudflare Turnstile work — with code you can copy today.

The ShipMyForm team

· 3 min read

You can stop almost all contact form spam without reCAPTCHA by layering a few quiet defenses — none of which ask your visitors to solve a puzzle. The two that work on any site, including a purely static one, are a honeypot field and server-side rate limiting. Add Cloudflare Turnstile for a form that gets actively targeted. Together they block the overwhelming majority of automated submissions.

Here's how each layer works and how to add it.

Why not reCAPTCHA?

reCAPTCHA works, but it comes with costs:

  • v2 ("select all the buses") adds friction and hurts conversion.
  • v3 is invisible but silently profiles every visitor and ties your form to Google, which is awkward for privacy and consent.
  • Both load third-party scripts on every page with a form.

Most contact-form spam is dumb automation, not a determined attacker. You can defeat dumb automation without taxing real people.

Layer 1: the honeypot

A honeypot is a hidden field a human never fills but a bot will. Add a field with a tempting name, hide it, and keep it out of the tab order:

html
<form action="https://shipmyform.com/f/YOUR_FORM_ID" method="POST">
  <!-- real fields -->
  <input type="email" name="email" required />
  <textarea name="message" required></textarea>

  <!-- honeypot: hidden from humans, irresistible to bots -->
  <input
    type="text"
    name="_gotcha"
    tabindex="-1"
    autocomplete="off"
    aria-hidden="true"
    style="position:absolute; left:-9999px"
  />

  <button type="submit">Send</button>
</form>

On the server, any submission where _gotcha is non-empty is treated as spam and dropped. ShipMyForm checks the _gotcha field for you — bots that fill it get a fake success response, so they don't learn they were caught.

Want the markup done for you? The free contact form generator builds a form with the honeypot (and optional Turnstile) already wired up — copy, paste, done.

Do the honeypot right:

Use CSS to hide the field (not type="hidden", which some bots skip), set tabindex="-1", autocomplete="off", and aria-hidden="true" so keyboard users, screen readers, and password managers never touch it.

Layer 2: rate limiting

Even if a bot clears the honeypot, it shouldn't be able to fire hundreds of submissions. Server-side rate limiting — per IP and per form — caps the damage. This has to live on the backend, which is one more reason to let a form backend handle submissions rather than rolling your own.

Layer 3 (optional): Cloudflare Turnstile

If a specific form gets singled out, add Cloudflare Turnstile — a free, privacy-respecting CAPTCHA alternative that's usually invisible. It drops a token into the form that the backend verifies:

html
<form action="https://shipmyform.com/f/YOUR_FORM_ID" method="POST">
  <input type="email" name="email" required />
  <textarea name="message" required></textarea>

  <!-- Turnstile injects a hidden cf-turnstile-response field -->
  <div class="cf-turnstile" data-sitekey="YOUR_SITE_KEY"></div>

  <button type="submit">Send</button>
</form>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>

ShipMyForm verifies the cf-turnstile-response token server-side when Turnstile is enabled on a form. Keep it off until you need it — the honeypot and rate limiting handle most sites on their own.

How the options compare

DefenseVisitor frictionPrivacyStopsEffort
HoneypotNoneGreatMost basic botsTrivial
Rate limitingNoneGreatFloodsBackend only
Cloudflare TurnstileVery lowGoodTargeted botsLow
reCAPTCHA v2HighPoorTargeted botsLow

The pragmatic recipe

For a typical contact form you don't need a CAPTCHA at all: a honeypot + rate limiting stops the bulk of automated spam, with Turnstile in your back pocket for a form that gets singled out. ShipMyForm applies the honeypot check, per-IP and per-form rate limiting, and origin allow-listing to every form automatically, with Turnstile a toggle away when you need it.

Next steps

Frequently asked questions

How do I stop contact form spam without a CAPTCHA?
Combine a honeypot field with server-side rate limiting — together they block the vast majority of automated spam with zero friction for real visitors. Add Cloudflare Turnstile if a form is actively targeted.
What is a honeypot field?
A honeypot is a hidden form field that real users never see or fill. Bots fill every field they find, so any submission with the honeypot populated can be silently rejected as spam.
Is Cloudflare Turnstile better than reCAPTCHA?
For most sites, yes: Turnstile is free, privacy-friendly, and usually invisible, so visitors aren't asked to solve image puzzles. reCAPTCHA v2 adds friction and reCAPTCHA v3 silently scores users but ties you to Google.
Does a honeypot hurt accessibility?
Not if you implement it correctly: hide the field with CSS, set tabindex to -1, and add autocomplete off and aria-hidden so screen readers and password managers skip it.

Related guides