
Your WordPress forms are where money enters your business. Every enquiry, quote request, booking and callback starts as a form submission – and yet forms are the most neglected part of most websites I audit. The home page gets redesigned twice a year; the contact form was configured once in 2019 and nobody has tested it since. In the last twelve years I have found dozens of sites whose forms had silently stopped delivering email for weeks or months. The owners thought business was slow. The truth was that their leads were going straight into a void.
This guide is everything I actually do when I build or fix forms for clients: how to choose a form plugin without falling for marketing, how to design a form that people finish, how to make delivery reliable (the wp_mail problem is real and it will bite you), how to stop spam in layers without punishing genuine visitors with puzzles, how to stay on the right side of GDPR, how to store enquiries cleanly inside WordPress, how to measure submissions as conversions in GA4, and how to test the whole chain every month so a plugin update never costs you a fortnight of leads again.
Table of contents
- Why most WordPress forms quietly fail
- Choosing a form plugin honestly
- Form design that converts
- Delivery reliability: the wp_mail problem and SMTP
- Spam protection in layers
- Turnstile vs reCAPTCHA: the privacy angle
- GDPR essentials for forms
- Storing enquiries in WordPress the clean way
- Tracking form submissions as conversions in GA4
- Test your forms monthly – here is the routine
- Frequently asked questions
Why most WordPress forms quietly fail
A form can fail in four distinct places, and the site owner usually only notices the loudest one. First, it can fail to convert: the visitor arrives, looks at eleven required fields and a file upload, and leaves. Nothing breaks, no error is logged, you simply never hear from them. Second, it can fail to deliver: the visitor submits, sees “Thank you, we will be in touch”, and the notification email lands in your spam folder or nowhere at all. Third, it can fail under spam: three hundred bot submissions a day bury the two real enquiries, and after a week of deleting junk you stop reading the folder at all. Fourth, it can fail legally: the form collects more personal data than it needs, with a pre-ticked consent box, stored forever, processed through services you never assessed – which in the EU and UK is not a hypothetical problem.
The frustrating part is that each failure mode hides the others. A site drowning in spam does not notice that real notifications stopped arriving. A form that converts poorly never generates enough submissions for the owner to spot the delivery problem. So the fix is never one plugin or one setting – it is a short chain of decisions, each of which takes minutes once you know what to do. That chain is this article.
- Conversion failure – the form asks too much, too awkwardly, and visitors abandon it.
- Delivery failure – submissions happen but notifications never reach a human inbox.
- Spam failure – bots flood the form until real enquiries are lost in the noise.
- Compliance failure – the form collects and stores personal data in ways GDPR does not allow.
Choosing a form plugin honestly
There are more form plugins than any other category in the WordPress ecosystem, and most comparison articles are affiliate marketing wearing a lab coat. Here is the honest version from someone who has built forms with all of them across 500+ projects.
For a simple contact form – name, email, message – almost anything works, including the free tier of nearly every plugin. The differences appear when you need conditional logic, multi-step layouts, calculations, payments, file uploads, entry storage with retention rules, or clean integrations with your CRM and email tools. That is when the plugin choice starts to matter.
| Plugin | Typical cost | Best for | Watch out for |
|---|---|---|---|
| Fluent Forms | Free tier; Pro from around USD 59/year | Most business sites – fast, complete, well priced | Fewer third-party add-ons than Gravity |
| Gravity Forms | From USD 59/year, realistic use USD 259/year | Complex logic, large ecosystem, agency standard | No free tier; heavier front-end output by default |
| WS Form | From around USD 49/year | Developers – clean markup, accessibility, performance | Smaller community, steeper learning curve |
| Contact Form 7 | Free | Minimal contact forms on a tight budget | Everything beyond basics needs extra plugins |
| Builder-bundled (Elementor, Divi) | Included in the builder licence | Quick forms inside builder layouts | Weak entry storage, weak spam tools, locked to the builder |
My default recommendation for a small business site is Fluent Forms: it is genuinely fast on the front end, the free version covers more than most sites need, entries are stored properly, and the Pro price is fair. Gravity Forms remains my choice for complex agency work – its ecosystem of add-ons is unmatched, and when a client needs a 40-field conditional quote engine with CRM sync, Gravity plus its add-ons is the safe bet. WS Form deserves more attention than it gets: it produces the cleanest, most accessible markup of the lot, which matters if performance and accessibility scores are contractual.
The one I steer clients away from is the builder-bundled form. The Elementor form widget is convenient, but its spam protection is thin, its entry handling is an afterthought, and the form dies with the builder if you ever migrate. A form is business-critical infrastructure; it should not be a side feature of your page builder. If you already run builder forms and they work, fine – but apply every delivery, spam and GDPR step below to them, because their defaults handle none of it well.
- Pick one plugin for the whole site. Two form plugins means two spam configurations, two SMTP paths and twice the update risk.
- Check the front-end payload. Some plugins load 300 KB of CSS and JavaScript on every page. Load form assets only where forms exist.
- Check entry storage and export. You will need it for the GDPR section below.
- Ignore lifetime deals from unknown vendors. A form plugin holds personal data; it needs a vendor who will still ship security fixes in five years.
Form design that converts
The most expensive form mistake is invisible: fields that scare people away. Every field you add gives the visitor another reason to leave, and most fields on most forms exist because someone in a meeting said “it would be nice to know”. It would be nice. It is also costing you enquiries.
For a standard contact or quote form, I push clients towards three to five fields: name, email, message, and at most one or two qualifiers that genuinely change how you respond (budget range, service needed). Phone number as an optional field, never required – a surprising number of people will abandon a form rather than hand over their number to a stranger. Company, address, “how did you hear about us”, preferred contact time: cut them. You can ask all of that in your reply, once a human relationship exists.
Beyond field count, the details that move completion rates in my experience:
- Labels above fields, always visible. Placeholder-only forms look tidy in a design mockup and fail in real use: the moment you start typing, the label vanishes, and on a five-field form people forget what the third field wanted. Placeholders are hints, not labels – screen readers agree.
- Inline validation, not a red wall. Tell people an email address is malformed while they are in the field, not after they hit submit and lose their scroll position. Every serious form plugin supports this; turn it on.
- 16px minimum font size on inputs. On iOS, any input below 16px triggers an automatic zoom when focused, which breaks the layout and disorients the visitor. This one CSS value fixes a real, measurable mobile annoyance.
- Tap targets and spacing on mobile. Full-width fields, generous vertical spacing, and a submit button you can hit with a thumb. Most of your form traffic is on a phone; design there first.
- Specific button text. “Get my free quote” or “Send my enquiry” outperforms “Submit”. The button should describe what the visitor receives, and the line under it should say what happens next: “I reply within 24 hours” does more for completion than any design flourish.
- Multi-step for long forms only. If you genuinely need ten or more inputs – detailed quote calculators, booking flows – break them into steps with a progress indicator, easiest questions first. One question per screen feels lighter than a wall of fields. But do not multi-step a contact form; three fields on one screen beats three screens of one field.
- No CAPTCHA puzzle as the last step. Making a human prove humanity by clicking traffic lights is a conversion tax. The spam section below shows how to avoid it almost entirely.
One more thing worth saying: the form’s position and framing matter as much as its fields. A form at the bottom of a persuasive page converts; the same form floating in a sidebar next to unrelated content does not. Put the form where the visitor has just finished reading the reason to use it, repeat it after long content, and give it a heading that states the benefit rather than the mechanism – “Get a fixed quote within 24 hours” beats “Contact form”.

Delivery reliability: the wp_mail problem and SMTP
Here is the failure that costs businesses the most money, and the one almost nobody checks. By default, WordPress sends every email – including your form notifications – through the PHP mail() function on your web server. That email leaves an IP address that mailbox providers do not associate with your domain, usually without proper SPF or DKIM alignment, from a shared server whose reputation depends on every other site hosted on it. Gmail and Outlook look at that message and, on a good day, put it in spam. On a bad day they silently drop it. Nothing in WordPress errors; the form says “sent” because handing the message to the server counts as sent.
The fix is to stop using bare wp_mail delivery and route everything through authenticated SMTP or a transactional email API. In practice:
- Install an SMTP plugin. FluentSMTP (free) or WP Mail SMTP are both fine. They intercept wp_mail and hand delivery to a real mail service.
- Connect a proper sender. Options, roughly in order of my preference for small sites: your own mailbox provider’s SMTP (Google Workspace or Microsoft 365 – simplest, uses your existing domain reputation), a transactional service such as Brevo, Postmark or Amazon SES (best deliverability at scale, generous free tiers), or your hosting company’s SMTP as a last resort.
- Set up SPF, DKIM and DMARC on your domain. Your email provider gives you the DNS records; add them once and delivery improves for everything you send. Without DKIM in particular, modern Gmail treats you with suspicion regardless of content.
- Configure the notification properly. Send from an address on your own domain (never from the visitor’s address – that fails DMARC instantly and is the single most common misconfiguration I find). Put the visitor’s address in Reply-To so you can answer with one click. Send to two recipients if the enquiry matters: your main inbox and a backup.
- Test the full round trip. Submit the form as a stranger would, and confirm the notification arrives in the actual inbox – not the site’s logs, the inbox. Then reply to it and confirm the reply goes to the visitor’s address.
Two supporting habits make this robust. First, keep entries stored in the database (next sections) so that even if email fails, the enquiry exists somewhere a human can find it. Second, turn on your SMTP plugin’s email log for a few weeks after any change – FluentSMTP shows you every message, its status and the provider’s response, which turns “I think emails work” into “I can see they work”.
Spam protection in layers
Form spam is not one problem, so it does not have one solution. The junk arriving in your inbox comes from three different sources: dumb bots that POST to every form they find without rendering the page, smarter bots that drive a real browser and fill fields like a human, and actual humans paid tiny amounts to submit promotional messages. Each layer of defence catches a different attacker, and the trick is to stack the invisible layers first so genuine visitors never see a challenge.
- Layer 1: honeypot. An extra field hidden from humans with CSS but visible in the HTML. Humans leave it empty; dumb bots fill everything and get rejected. Free, invisible, built into every good form plugin – just confirm it is switched on. This alone kills a large share of the junk.
- Layer 2: time-trap. A human takes at least a few seconds to read and fill a form; a bot submits in under one. Rejecting submissions that arrive faster than three seconds after page render catches script bots the honeypot misses. Fluent Forms and WS Form have this built in; Gravity has add-ons.
- Layer 3: an invisible challenge – Cloudflare Turnstile. For the browser-driving bots, add Turnstile. It scores the visitor’s environment invisibly and almost never shows an interactive prompt to real people. This is the layer that replaces the traffic-light puzzles of old.
- Layer 4: content rules. Block submissions containing links in the message field if your audience never sends them, and keyword-filter the usual pharmaceutical and SEO-offer vocabulary. Most plugins support a blocklist; Akismet or CleanTalk can do this centrally if volume is high.
- Layer 5: a monitored inbox. Whatever slips through gets seen and used to tune the layers above – a new keyword added, a country blocked if you only serve one market. Spam protection is a dial you adjust twice a year, not a wall you build once.
Two things I tell every client. First, add layers one at a time and check the entry log after each: an over-aggressive time-trap or keyword rule silently rejects real customers, which is worse than spam. Second, never rely on a single CAPTCHA as your whole defence – it filters the bots but also filters humans, and the humans it filters were about to pay you. Spam that reaches your inbox costs you seconds; a blocked customer costs you the job. The tuning goal is always: zero friction for humans, layered friction for bots. Bot traffic hammering your forms is also a security signal worth watching – the same scripts probe login pages and vulnerable plugins, which I cover in common WordPress security mistakes.

Turnstile vs reCAPTCHA: the privacy angle
If you add a challenge layer, the honest comparison today is Cloudflare Turnstile against Google reCAPTCHA – and I now specify Turnstile on almost every build, for three reasons.
User experience. Turnstile runs invisibly or shows a simple checkbox; it does not ask humans to identify buses. reCAPTCHA v2’s image puzzles are a proven conversion killer, and reCAPTCHA v3, while invisible, scores users and quietly fails the ones with privacy-friendly browsers, VPNs or cookie-blocking extensions – which increasingly describes your most security-conscious customers.
Privacy and GDPR posture. reCAPTCHA sends visitor data – IP address, browser fingerprint, cookie data – to Google, and how that data is used beyond bot scoring is not something you can fully explain in a privacy policy. European data protection authorities have repeatedly questioned reCAPTCHA’s compliance; French and German regulators have both raised the consent problem: strictly, you need the visitor’s consent before loading it, and a form guarded by a tool that itself requires a consent banner is a circular headache. Turnstile is explicitly designed to avoid this – no cookies for its core operation, no fingerprint-based advertising business behind it – which makes it far easier to justify under legitimate interest.
Performance. The Turnstile script is lighter and does not drag the rest of Google’s ecosystem onto your page. On performance-audited sites, replacing reCAPTCHA with Turnstile is a small but free win.
Turnstile is free, and every major form plugin now integrates it natively – paste two keys from a Cloudflare account and you are done. The only case where I still see reCAPTCHA earning its place is Enterprise deployments already deep in Google Cloud tooling. For a small business site in Europe, Turnstile is the easy, defensible choice.
GDPR essentials for forms
Forms are where GDPR stops being abstract: the moment a visitor types their name and email, you are processing personal data and the regulation applies. The good news is that a contact form done properly needs surprisingly little ceremony. The essentials, as I implement them:
- Collect the minimum. Data minimisation is a core GDPR principle and also, conveniently, the same advice as the conversion section: every field must justify itself. If you cannot say why you need the phone number, you may not collect it – and you will convert better without it.
- Know your legal basis. Answering an enquiry someone sent you does not need a consent checkbox – responding to their request is a legitimate interest (or a pre-contractual step). What does need explicit consent is anything extra: adding them to a newsletter, marketing follow-ups, sharing with partners.
- Checkbox rules, when you need one: unticked by default, always; one purpose per checkbox (no “I agree to the privacy policy and marketing” bundles); marketing consent never a required field on a contact form; and a link to the privacy policy next to the form. A pre-ticked box is not consent under GDPR – full stop.
- Storage and retention. Form entries stored in WordPress are personal data at rest. Decide a retention period (12 months is a defensible default for enquiries), write it in your privacy policy, and enforce it – Fluent Forms and Gravity can auto-delete entries after a set period, or trim them on a schedule. “We keep everything forever because nobody set up deletion” is the most common violation I see, and the easiest to fix.
- Where the data travels. List every service your form data touches: the SMTP or email provider, the CRM, the spam service, the CAPTCHA vendor. Each is a processor; each should have a data processing agreement (all the mainstream ones publish theirs), and transfers outside the EU need a recognised mechanism. Choosing EU-region processing where offered – Brevo’s EU servers, EU data centres for your CRM – shortens this conversation considerably.
- Be able to answer requests. If someone asks what you hold about them, or asks you to delete it, you need to search and delete their form entries too – not just your inbox. Storing entries in one plugin, cleanly, makes this a two-minute task; most good form plugins integrate with WordPress’s built-in export and erase tools.
Forms are one corner of site-wide compliance – cookies, analytics, embeds and hosting all have their own rules, and I have covered the full picture in my GDPR compliance guide for WordPress websites. But if you fix only your forms – minimal fields, honest checkboxes, a retention rule and a processor list – you have fixed the part regulators and users actually see.
Storing enquiries in WordPress the clean way
Every submission should exist in two places: the notification email and a database entry inside WordPress. The email is for speed; the entry is your safety net when email fails, your audit trail, and your GDPR-searchable record. But storage done carelessly creates its own problems, so here is the clean version.
- Use the plugin’s entry system, not a DIY solution. Fluent Forms, Gravity and WS Form all store entries with the submission time, the page it came from and the delivery status. Contact Form 7 does not store anything by default – add Flamingo if you stay with it, because a form with no entry log fails silently by design.
- Restrict who can read entries. Enquiries contain personal data, so entry access belongs to specific roles, not every author and shop manager account on the site. Check the plugin’s capability settings once; it takes five minutes.
- Never store what you must not. No card numbers, no passwords, no health details in free-text fields if you can avoid inviting them. If your form takes payments, the card data must go straight to Stripe or PayPal and never touch your database – every serious payment add-on works this way, but check before you trust a niche one.
- Apply the retention rule. The auto-deletion schedule from the GDPR section lives here. Old enquiries are a liability, not an asset: in a breach, ten years of stored enquiries is the difference between an embarrassment and a reportable incident.
- Mind the database size. On high-traffic sites, entry tables (and their spam) grow into hundreds of thousands of rows and slow the admin. Retention rules solve this too; delete spam entries weekly rather than letting them accumulate.
- Route entries onwards automatically. If enquiries should end up in a CRM, connect the form to it directly (native integrations or webhooks) rather than copy-pasting from email. Fewer manual steps means fewer lost leads, and the CRM becomes the long-term record so WordPress can keep its short retention window.
The pattern I set up for most clients: entry stored in WordPress with a 12-month auto-delete, notification to two inboxes via SMTP, and a webhook or native integration pushing the lead into whatever the client uses to manage work – even a Google Sheet beats an inbox as a pipeline. WordPress is the reliable capture point, not the permanent archive.
Tracking form submissions as conversions in GA4
If you do not measure submissions, you cannot know whether any of the above worked – and “the form feels quiet lately” is how delivery failures survive for months. Google Analytics 4 makes this measurable in an afternoon.
- Decide what counts as a submission. The reliable trigger is the form plugin’s success event – the moment the plugin confirms the entry was accepted. A click on the submit button is not a submission (validation may fail); a page view of a generic thank-you URL is better, but only if that URL is unreachable any other way.
- Send an event to GA4. The easy path: most form plugins fire a JavaScript event or integrate with Google Tag Manager on success. In GTM, listen for the plugin’s submit-success event and forward a clearly named GA4 event such as generate_lead with the form’s name as a parameter. If you use a thank-you page instead, register that page view as the event – simpler, and fine for a single form.
- Mark it as a key event. In GA4’s admin, flag your generate_lead event as a key event (Google’s current name for conversions). Now every report – traffic sources, landing pages, campaigns – can show which visitors actually enquire, not just which visitors arrive.
- Keep spam out of the numbers. Fire the event only after the spam layers pass, which the plugin’s success event does automatically (rejected submissions never succeed). If you track a thank-you page instead, spam that beats your filters inflates your conversion data – one more argument for the event-based route.
- Watch the trend, not the day. The practical value is the baseline: if your form converts around 2-3% of visitors and that number halves, something broke – a plugin update, a new consent banner blocking the tracking, a broken field on mobile. The chart notices before you do.
One honest caveat: GA4 only sees visitors who accepted analytics cookies, so under a GDPR-correct consent banner your conversion counts will undercount reality. That is fine – trends survive undercounting. Cross-check against the entry log monthly (entries are the truth; GA4 is the trend line) and resist the temptation to “fix” it by firing analytics before consent.
Test your forms monthly – here is the routine
Everything above decays. Plugin updates change markup, SMTP passwords expire, API keys get rotated, a well-meaning edit deletes the Turnstile keys, your email provider tightens a policy. Forms do not fail loudly – they fail silently, which is why testing has to be a routine, not a reaction. Mine takes under ten minutes a month per site:
- Submit every form on the site as a visitor – from an incognito window, on a phone for at least one of them, with a realistic message (“TEST” in the subject so it is filterable).
- Confirm the notification arrived in the actual inbox, not spam, within a couple of minutes – and that Reply-To points at the test sender.
- Confirm the entry was stored and its delivery status is green in the plugin’s log.
- Confirm the GA4 event fired – check the realtime report while submitting.
- Skim the SMTP log and spam folder for the past month: any failed sends, any real enquiries wrongly caught by the spam layers?
- After any major plugin, theme or PHP update, test immediately – do not wait for the monthly slot. Form breakage after updates is the single most common cause of the “quiet month” I get called about.
This routine slots into normal site maintenance alongside updates, backups and security checks – the full schedule is in my WordPress maintenance checklist. If nobody currently does this for your site, that is the gap to close first, because every other improvement in this article is temporary without it. A form that was perfect in January and untested since is, statistically, broken by August.
Want forms that convert, deliver and comply – without the headaches?
I build and fix WordPress forms as part of custom WordPress development projects and keep them tested and spam-free under maintenance and security plans – SMTP delivery, layered spam protection, GDPR-clean setup and GA4 tracking included, at EUR 15/hour or a fixed price. See my portfolio or send me a message – through a form built exactly this way – and I reply within 24 hours.
Frequently asked questions
What is the best WordPress forms plugin?
For most business sites, Fluent Forms – fast, well priced, with proper entry storage and spam tools. Gravity Forms for complex logic and integrations, WS Form for developer-grade markup, and I recommend avoiding builder-bundled forms for anything business-critical.
Why is my WordPress form not sending emails?
Almost always because WordPress is sending through the server’s PHP mail() function, which mailbox providers distrust. Install an SMTP plugin, connect a real email service, add SPF and DKIM records, and send from your own domain with the visitor in Reply-To.
How do I stop spam on WordPress forms without a CAPTCHA?
Layer invisible defences: a honeypot field, a time-trap rejecting sub-3-second submissions, and content rules for links and keywords. That combination stops most spam with zero visitor friction; add invisible Cloudflare Turnstile only if bots still get through.
Is Google reCAPTCHA GDPR compliant?
It is legally uncomfortable in the EU: it sends visitor data to Google, and regulators have questioned whether it needs prior consent. Cloudflare Turnstile does the same job with a far cleaner privacy posture, so it is the easier tool to defend.
Do I need a consent checkbox on my contact form?
Not for simply answering the enquiry – that is a legitimate interest. You need an unticked, separate checkbox only for extras such as newsletter signup or marketing follow-up, plus a visible link to your privacy policy.
How long can I keep form submissions under GDPR?
Only as long as you have a reason. For general enquiries, a stated retention period of around 12 months with automatic deletion is a defensible, easy-to-implement default.
How many fields should a contact form have?
Three to five: name, email, message, and at most one or two qualifiers that change how you respond. Every additional required field measurably reduces completions – ask everything else in your reply.