Spam Protection

CAPTCHA, honeypot fields, and language detection to keep spam out.

View .md
On this page

StaticForm includes multiple layers of spam protection that work together to block unwanted submissions.

CAPTCHA

StaticForm supports the following CAPTCHA providers:

ProviderDescription
reCAPTCHA v3Google’s invisible CAPTCHA, no user interaction needed
reCAPTCHA v2Google’s classic “I’m not a robot” checkbox
hCaptchaPrivacy-focused alternative to reCAPTCHA
TurnstileCloudflare’s CAPTCHA, fast and privacy-friendly

Setup

  1. Get a site key and secret key from your CAPTCHA provider
  2. In your form settings, select the CAPTCHA type and enter the secret key (both reCAPTCHA v2 and v3 use the reCAPTCHA option)
  3. Add the CAPTCHA script and widget to your frontend
  4. On submit, send the resulting token to StaticForm under the field name the provider expects (see below)

How CAPTCHA tokens reach StaticForm

When a CAPTCHA is enabled on a form, StaticForm expects every submission to include a token field in the POST body. The field name depends on the provider:

ProviderForm-data field
reCAPTCHA v2 / v3g-recaptcha-response
Cloudflare Turnstilecf-turnstile-response
hCaptchah-captcha-response

If the field is missing or the token fails verification, the submission is rejected with a CAPTCHA error.

How the token gets there depends on which provider you use:

  • reCAPTCHA v2, Turnstile, and hCaptcha all render a widget into your page (a checkbox or invisible challenge). Once the user solves it, the provider’s script automatically injects a hidden <input> with the right name and value into the surrounding <form>. As long as the widget lives inside the form, a regular HTML submit or a new FormData(form) call will pick the token up automatically. You don’t have to write any JavaScript.

  • reCAPTCHA v3 is invisible and has no widget, so there is no hidden input. You have to call grecaptcha.execute(siteKey, { action }) yourself, get back a token, and append it to your form data as g-recaptcha-response before submitting.

In short: for the three widget-based providers, dropping the right <div> inside your form is enough. For reCAPTCHA v3, you have to wire up the token injection in JavaScript.

Use the JavaScript helper if you’d rather not handle this yourself

If you don’t want to manage scripts, widgets, and token plumbing by hand, the StaticForm JavaScript helper does it for you. It supports all four providers, auto-loads the provider’s <script> tag for you, programmatically generates a fresh reCAPTCHA v3 token on every submit, picks up the token from the rendered widget for v2/Turnstile/hCaptcha, and resets the widget after each submission so users can submit again:

// reCAPTCHA v3 (invisible, generates tokens programmatically)
StaticForm.attach(form, {
  endpoint: 'https://api.staticform.app/api/v1/forms/YOUR_FORM_ID',
  captcha: { type: 'recaptcha-v3', siteKey: 'YOUR_SITE_KEY' },
});

// reCAPTCHA v2 / Turnstile / hCaptcha
// (render the provider's widget inside your form, then:)
StaticForm.attach(form, {
  endpoint: 'https://api.staticform.app/api/v1/forms/YOUR_FORM_ID',
  captcha: { type: 'turnstile' }, // or 'recaptcha-v2' or 'hcaptcha'
});

See the JavaScript helper docs for the full setup (script tags, widget markup, and config) of each provider.

Honeypot

A honeypot is a hidden field that real users won’t fill out but spam bots will. If the field has a value, the submission is flagged as spam.

Setup

Enable the honeypot in your form settings and choose a field name (default: website_url). Then add a hidden field to your HTML:

<div style="display: none;" aria-hidden="true">
  <input type="text" name="website_url" tabindex="-1" autocomplete="off" />
</div>

Tip: Use a field name that looks like a real field (like website_url) to trick bots into filling it out.

Language Detection

Language detection analyzes the text content of submissions and flags those that don’t match your expected languages.

Setup

  1. Enable language detection in your form settings
  2. Set your expected languages using ISO 639-2/T codes (3-letter, e.g. eng, deu, fra)
  3. Optionally specify which fields to check (defaults to all text fields)

This is useful if your form targets a specific audience and you want to filter out submissions in unexpected languages.

IP-Based Analysis

For client-side submissions, StaticForm performs IP-based analysis to detect known spam sources. This runs automatically and requires no configuration.

Note: IP-based analysis is skipped for server-side submission mode since server IPs are expected.

Spam Management

All submissions include a spam probability score. In the dashboard you can:

  • View spam scores and detection categories for each submission
  • Manually mark submissions as spam or legitimate
  • View separate spam and legitimate submission lists
Spam detection details for a submission