Your contact form used to bring in a few enquiries a week. Now it brings in dozens of messages a day, and almost all of them are rubbish: offers to “rank your site”, links to sites you would never click, strings of random letters, or the same message in five languages. Somewhere in that pile there may be one real customer, and you are starting to miss them.
The obvious fix is to bolt on the hardest puzzle you can find. That usually works against bots and against customers in equal measure. This post is about stopping contact form spam in layers, so that the filtering happens out of sight and the person with a real question never notices it.
Where the spam is coming from
It helps to know what you are fighting, because the fixes differ.
- Bots that fill in every field they find. They read the page code, not the page, and submit the form directly. These are the simplest kind to stop.
- Bots that skip your page entirely. Some scripts post straight to the address the form submits to, without loading the page at all. Anything that relies on the visitor running JavaScript on your page catches these.
- Real people paid to send messages. These pass any test designed to tell humans from software, because they are humans. You can only reduce them with content rules, not puzzles.
- Abuse of your form to reach someone else. If your form sends an automatic “thanks for your message” copy to the address typed in, a spammer can type a stranger’s address and use your site to send them junk. Your server gets the blame.
If your problem is comments rather than the contact form, that is a separate system with its own settings, covered in our guide to stopping WordPress comment spam.
Layer one: checks the visitor never sees
Start here, because these cost a genuine visitor nothing.
A honeypot field
A honeypot is an extra field hidden from people but present in the page code. A person never fills it in, because they cannot see it. A careless bot fills in everything. Any submission with that field filled is thrown away. Most of the well-known form plugins, including WPForms and Gravity Forms, offer a honeypot as a setting, and add-ons exist for Contact Form 7. It will not stop a clever bot, but it removes a surprising amount of noise for free.
A time check
People take a few seconds at least to read a form and type a message. A script can submit it the instant the page loads. Some plugins reject anything submitted faster than a person could plausibly type. Set it gently, so that someone using autofill on their phone is not caught.
An invisible challenge
Services such as Google reCAPTCHA v3 and Cloudflare Turnstile run in the background and judge whether the visitor behaves like a person. Most visitors see nothing at all. Turnstile in particular is designed to avoid the “click every traffic light” puzzle. Both need a site key, and both depend on loading a script from that provider, so mention them in your privacy policy.
The trade-off: these services make a judgement, and a judgement can be wrong. A visitor on a VPN, a shared office connection or an older browser may get flagged. That is why the next section matters.
Layer two: rules about the content
Human spammers and better bots get past the first layer. Content rules catch a lot of what remains.
- Akismet can check form submissions as well as comments, and Contact Form 7 supports it directly. It compares the message against patterns it has seen across many sites.
- Block messages with several links. Real enquiries rarely contain more than one link. A rule that blocks or flags messages with three or more catches much of the SEO and casino spam.
- Use field types properly. A phone field that accepts only digits and a few symbols, and an email field that must look like an email, quietly reject a lot of junk.
- Blocklist the repeat offenders. If the same phrases or the same sending domains keep turning up, most form plugins or security plugins let you block them by word or domain.
Be careful with language-based blocking. Rejecting every message that is not in English might sound tidy, but if you sell abroad, or a customer writes with a few words in Hindi or German, you will lose them without knowing.
Layer three: do not let filtering lose real enquiries
This is the part most people skip, and it is the reason many owners believe their form “just stopped working”.
Store every submission, not just the email. Turn on your form plugin’s entry storage, or for Contact Form 7, install its companion plugin Flamingo. Then a message that was filtered, or an email that never arrived, still exists in the dashboard. Check the spam folder of that store once a week for the first month after changing anything, so you learn whether your rules are too strict.
Mark spam instead of deleting it, where the plugin allows. A flagged message you can look at is far better than one that silently vanished.
Give people a second route. A phone number, a WhatsApp button or a plain email address on the contact page means that if a filter misjudges someone, they still reach you.
If the form is quiet and you are not sure whether it is the spam rules or the email delivery that is failing, start with why a WordPress contact form stops sending. A form that sends from the visitor’s own address is often the real culprit, and the background to that is in our plain explanation of SPF, DKIM and DMARC.
Close the “copy to sender” loophole
If your form emails a copy of the message to whatever address was typed in, you have built a small spam relay. Anyone can fill your form with an advert, put a stranger’s email in the address field, and your server delivers it. Enough of that and your domain’s mail reputation suffers, which can push your own normal emails into spam folders.
The fix is simple. Either switch off the copy to the sender, or make the automatic reply a short fixed message that contains none of what the visitor typed. A plain “We have received your message and will reply soon” is useless to a spammer.
What to avoid
- Hard visual puzzles. They annoy everyone, they are hard to use on a small phone screen, and they are a real barrier for visitors with poor eyesight. Many bots get past them anyway.
- Maths questions in a fixed spot. A “what is 3 + 4” field is better than nothing, but well-known versions are already handled by spam scripts.
- Stacking three anti-spam plugins. They conflict, they slow the page, and when something goes wrong it is hard to tell which one rejected the message.
- Forgetting to test. After every change, send yourself a real enquiry from your phone, on mobile data, not your office Wi-Fi. If you do not receive it, neither will a customer.
A sensible order to work in
- Turn on entry storage so nothing gets lost while you experiment.
- Switch on the honeypot in your form plugin.
- Remove or neuter the copy-to-sender email.
- Add an invisible challenge such as Turnstile or reCAPTCHA v3.
- Add Akismet or a link-count rule if human spam is still getting through.
- Send a test from your phone, and check the stored entries weekly for a few weeks.
Most sites never need to go past step four. Do one change at a time, so that if real enquiries drop off you know which step to undo.
If you would rather not fiddle with it
Getting the balance right is mostly patience: one change, a test, a week of watching. If the form is part of how you earn and you would like someone to set the layers up and test them properly, our one-time website services include a Contact Form Fix from ₹999 onwards. If the real problem turns out to be email delivery rather than spam, that is part of what gets checked.
Next in this series: WooCommerce Store Security: Protecting Your Checkout