Contact form for WordPress websites
Skip Contact Form 7, WPForms, Gravity Forms, Forminator, and the rest of the bloated plugin economy. One `
What your WordPress contact form actually looks like.
Drop-in form backend with spam filtering, signed webhooks, and a real submissions dashboard. The same code in this preview is what you copy into your WordPress project — no SDK, no plugin, no PHP.
- ✓1,000 submissions per month, free forever
- ✓Honeypot + AI spam classifier on every plan
- ✓Signed webhooks to Slack, Discord, your server
Ship a WordPress contact form without a backend.
No SDK, no PHP, no plugin. Your form posts standard FormData to one URL — submissions land in your inbox.
Get your free access key
Verify your email and your access key is generated instantly. Free for 1,000 submissions per month, forever.
By signing up, you agree to our terms and privacy policy.
Drop in the WordPress code
Copy the WordPress snippet on the right and paste it into your project. Replace YOUR_ACCESS_KEY with the key from step 1.
Submissions land in your inbox
Hits your dashboard and email in seconds. Forward to Slack, Discord, Sheets, Notion, or any signed webhook URL.
Try it now — no signup, no key.
This is a styled HTML preview of what your WordPress form will look like. Submitting opens a confirmation, no real request is sent.
Your WordPress form posts FormData to /api/submit. Splitforms validates the access key, runs the spam classifier, and forwards the parsed submission to your inbox plus the dashboard.
- →14ms median round-trip from the edge.
- →Honeypot + classifier, no CAPTCHA.
- →Per-domain key locking out of the box.
{
"access_key": "sk_live_4f9a_••••",
"name": "Maya Iyer",
"email": "maya@studio71.co",
"message": "…"
}How to ship this without regrets.
Five rules that make the difference between a form that works in the demo and a form that survives launch traffic.
- 01
Define the access key as a constant in `wp-config.php` (above the 'stop editing' line). Keeps it out of your theme repo and works for both staging and production via environment.
- 02
Use a Custom HTML block in the block editor for one-off contact pages — survives theme switches, no template editing required.
- 03
For headless WordPress (with Next.js, Astro, etc.), there's no PHP involved — use the framework-specific snippet from the matching /forms/<framework> page.
- 04
Skip every CAPTCHA plugin. WordPress sites are spam magnets, but splitforms's honeypot + classifier handles bot traffic without making humans solve puzzles.
- 05
If you're on Bedrock or Sage, define the key in `.env`: `SPLITFORMS_KEY=sk_live_…` and read it via `env('SPLITFORMS_KEY')` in your blade/twig template.
What bites people who skip the docs.
Worth a 60-second skim before you ship to production. Each one has caused a WordPress support ticket at least once.
WordPress wpautop() mangles your form HTML in posts
If you paste a <form> directly into a Classic Editor post, WordPress's wpautop filter wraps random <p> tags around your inputs and breaks the markup. Use a Custom HTML block (block editor) or a theme template file instead — wpautop doesn't touch those.
Caching plugins (WP Rocket, W3 Total Cache) cache the form page itself
Page caching is fine — your form posts to splitforms.com directly, not a WordPress endpoint, so the cached HTML still works. But if you ever switch to a WP-side handler (e.g. wp_ajax), exclude /contact/ from the page cache or submissions will hit a stale page.
Theme-injected JavaScript can hijack form submission
Some themes (Astra, OceanWP, GeneratePress 'Premium') auto-attach AJAX handlers to every form on the page. Add data-no-ajax="true" or a custom class your theme excludes — or use a Custom HTML block which most themes leave alone.
Cloudflare Bot Fight Mode blocks splitforms responses
If you proxy your WP site through Cloudflare with Bot Fight Mode on, the redirect from splitforms.com → /thanks may be flagged. Whitelist your domain in splitforms's allowed-domains list AND ensure /thanks is reachable without a Cloudflare challenge.
Hardcoded YOUR_ACCESS_KEY in the PHP example needs escaping
The snippet shows <?php echo esc_attr( YOUR_ACCESS_KEY ); ?> as a placeholder. In real code, define your key as a constant in wp-config.php: define('SPLITFORMS_KEY', 'sk_live_…'); then echo esc_attr(SPLITFORMS_KEY). Don't paste the literal string into theme files.
Wordfence and other security plugins block external form POSTs as 'leaving WordPress'
Wordfence's Live Traffic and 'Block fake Google crawlers' rules flag form submissions to non-WordPress domains as suspicious outbound activity from a logged-out user. The submission still goes through (the browser POSTs directly, bypassing PHP), but Wordfence may rate-limit or temporarily IP-ban the visitor's session, breaking subsequent page loads. Whitelist splitforms.com under Wordfence → Firewall → Allowlisted Services, or move to iThemes Security / Solid Security which handles outbound endpoints more gracefully.
How WordPress handles forms without splitforms.
The shape of the problem before splitforms enters the picture — and the gap it fills for WordPress specifically.
WordPress core has no contact-form feature — every contact form on a WP site is either a plugin (Contact Form 7, WPForms, Gravity Forms, Forminator, Fluent Forms, Ninja Forms) or a custom theme template. Plugins add 3-7 database tables, increase TTFB by 50-300ms, and most require a paid SMTP plugin (WP Mail SMTP) on top because shared-host PHP mail() lands in spam. CF7 alone is 1.2MB of JS/CSS loaded on every page. Anti-spam is a separate Akismet subscription ($10/mo for commercial use) or a paid CAPTCHA plugin. Splitforms replaces the plugin: a <form> tag in a Custom HTML block, pointing at our endpoint, with a hidden access_key field. No plugin, no extra DB tables, no SMTP gymnastics.
Two ways to ship splitforms on WordPress.
Pick the pattern that matches your constraints — JS budget, key-exposure tolerance, server-side opacity. Both produce the same result.
Pattern A — Custom HTML block (Block Editor / Gutenberg)
Drop a Custom HTML block on any page or post. Survives theme switches and plugin updates. No PHP required, no theme file editing. Reusable Patterns let you save the form once and drop it on every page.
Pattern B — theme template with key from wp-config constant
For developer-managed themes (Bedrock/Sage/classic), define SPLITFORMS_KEY as a constant in wp-config.php and echo it via esc_attr(). Keeps the key out of the theme repo, lets staging and production read different keys via environment.
Shipping WordPress + splitforms to production.
Host-specific gotchas, env-var conventions, and the boring-but-load-bearing details for putting this on the public internet.
WordPress runs on shared hosts (Bluehost, Hostinger), managed WP hosts (Kinsta, WP Engine, Pressable), or self-hosted Apache/nginx. The form's POST is cross-origin to splitforms.com, so the host doesn't matter for delivery. Caching plugins (WP Rocket, W3 Total Cache, LiteSpeed Cache) cache the page that hosts the form — that's fine, the form action URL is static. Don't proxy through WP's admin-ajax.php or wp_remote_post — adds latency and re-introduces the SMTP problem. For Multisite, use one access key per site or a shared key with form-name to disambiguate. Headless WP (Next.js/Astro front) doesn't involve PHP at all — use the matching framework's snippet.
splitforms vs native wordpress.
What you get for free vs what you build, pay for, or do without.
Block editor (Gutenberg) variant — Custom HTML block
If you prefer not to touch theme files, paste this directly into a Custom HTML block on any page or post. Survives theme switches and plugin updates.
Things developers ask before they integrate.
Direct answers, no marketing fluff. Missing one? Email hello@splitforms.com.
Ship your WordPress contact form in 60 seconds.
1,000 free submissions per month. No credit card. Lock the access key to your domains, paste the snippet, watch submissions land in your inbox.
