The form said thank you. The email never left
"sent": false, which nobody sees unless they open the browser's Network tab.You test your contact form, it shows a friendly message, and the email never comes. Or a customer calls to ask why you never answered. The form itself is rarely broken. A WordPress form plugin does two jobs, taking the message and emailing it to you, and the second job is handed to WordPress, which hands it to your server. In our test, that last hand-off is where every message died.
We wanted to see this from both sides, so on 10 November we put a fresh WordPress 7.1.3 in a Docker container on our server. The official image has no mail program, which is roughly what you get on a host that has switched PHP's mail() off. We installed Contact Form 7, Ninja Forms and WPForms Lite, left their default forms as they were, sent each one the request its own JavaScript sends, and wrote down what WordPress said about the email.
| Plugin | What the visitor saw | What wp_mail() reported | Copy of the message kept? |
|---|---|---|---|
| Contact Form 7 6.2.4.1 | “There was an error trying to send your message. Please try again later.” | Could not instantiate mail function. | No. The plugin has no table for messages |
| Ninja Forms 3.16.1 | “Form submitted successfully. A confirmation email was sent to emily.carter@example.com.” | Could not instantiate mail function, for both emails | Yes, under Ninja Forms → Submissions |
| WPForms Lite 2.0.4 | “Thanks for contacting us! We will be in touch with you shortly.” | Could not instantiate mail function. | No. Lite created no entries table |
Contact Form 7 was the only one to admit the failure. Ninja Forms and WPForms said thank you, and Ninja Forms went further and told the visitor a confirmation email was on its way. A success message on your form, then, says nothing about the email. With Contact Form 7 and WPForms Lite, the email that failed was also the only copy of the message.
Whatever plugin you use, the email can stop in one of three places. The message never reaches WordPress; WordPress tries to send it and fails; or the email leaves your server and is refused or filtered on the way. Each has its own test, so go through them in that order instead of trying fixes at random.
Did the message reach WordPress?
No mail setting will help if the submission never gets to WordPress, so rule that out first. Send a test from the live page in a private window. Logged in as an admin you may see details a visitor never sees, which is handy later but misleading now.
If the form shows its normal success or error message, the submission reached WordPress. If the button keeps spinning, or nothing happens, it didn't. The usual causes are a security plugin or firewall blocking the request, and a cached copy of the page whose security token has expired. In our Contact Form 7 test, blocking the REST API for visitors left the spinner turning with no message at all; in our Elementor test, a stale token got a 403 response with the body -1. Open the browser's developer tools on the Network tab, submit again, and look at the request the form sends. Anything other than a 200 points at caching or security, not mail. Exclude the contact page from your page cache and check the firewall's log for blocked requests. If neither explains it, try the form on a staging copy with a default theme and every plugin except the form plugin switched off, then turn them back on one at a time until it breaks again.
If your plugin keeps submissions, look there too. In our test Ninja Forms saved the message even though both emails failed, so a full Submissions screen with an empty inbox means the form is fine and only the email is broken.
Does WordPress fail to send the email?
Plugins don't say why an email failed. WordPress knows, and you can make it tell you in two ways, neither of which needs a plugin.
The quickest one is your login page. Log out, or open a private window, click “Lost your password?” on wp-login.php and enter your username. That makes WordPress send an email through the same function your form uses. On our broken server the page answered with “Error: The email could not be sent. Your site may not be correctly configured to send emails.” If you see that, the problem is the site's mail, not the form, and the next section fixes it. If instead you are told to check your email and the reset link arrives, WordPress can send, and the problem is in the form's settings or further down the line. Don't count on Site Health for this: we checked its code in WordPress 7.1.3 and it never sends or even mentions email. The email tests you may have read about come with SMTP plugins.
For the actual reason, add a tiny must-use plugin. Save the code below as wp-content/mu-plugins/log-mail.php, creating the mu-plugins folder if your site doesn't have one. WordPress runs everything in that folder on every request, so there is nothing to activate. Then submit your form once and open wp-content/mail-log.txt.
What you find there narrows it down. If the file has no new line at all, your plugin never asked WordPress to send anything. Check that the notification is switched on, that its conditional logic matches your test, and that a spam check didn't stop the message first. A line ending in “handed over” means WordPress passed the email on, so skip to the part about refused mail below. A line starting with FAILED gives you the reason, and these are the ones we saw.
“Could not instantiate mail function.” means PHP's mail() could not run, because the server has no mail program or the host has switched it off. That is what every plugin hit on our test server. “SMTP Error: Could not connect to SMTP host. Failed to connect to server” appeared once we had an SMTP plugin set up with a wrong port: the plugin is there, but the mail server can't be reached, often because the host blocks that port. Try the other port your mail provider lists, usually 587 or 465. If the log says the SMTP login failed, our guides to Gmail's 535 error and Office 365's 535 error cover the usual causes. And “Invalid address: (From)” means the From address itself was rejected before anything was sent, which we hit in our Elementor test on a site whose From address came out as email@localhost.
When you've found the cause, delete log-mail.php again. It writes a line for every email the site sends, password resets and order emails included, and nothing ever trims that file.
<?php
// wp-content/mu-plugins/log-mail.php
// One line in wp-content/mail-log.txt for every email WordPress tries to send.
add_action( 'wp_mail_failed', function ( $error ) {
file_put_contents( WP_CONTENT_DIR . '/mail-log.txt',
gmdate( 'c' ) . ' FAILED ' . $error->get_error_message() . "\n", FILE_APPEND );
} );
add_action( 'wp_mail_succeeded', function ( $mail ) {
file_put_contents( WP_CONTENT_DIR . '/mail-log.txt',
gmdate( 'c' ) . ' handed over: ' . $mail['subject'] . "\n", FILE_APPEND );
} );Fix a failing wp_mail(): send through SMTP
By default WordPress sends mail with PHP's mail(), which passes the email to whatever mail program the server has. Some hosts limit it or switch it off, and even when it works, the mail comes from a server that nobody has said may send for your domain. Our PHP mail() guide shows that part in detail. An SMTP plugin replaces that hand-off: WordPress logs in to a real mail account and sends through it, the way your email app does.
We checked the fix on the same broken server. We installed WP Mail SMTP, the one most guides recommend (FluentSMTP and Post SMTP do the same job), pointed it at a test mail server, and set it to force the From address to forms@olive-bakery.test, an address on the test site's own domain. Without changing a single form setting, Contact Form 7 switched to “Thank you for your message. It has been sent.”, Ninja Forms' email action reported "sent": true, and all six emails we sent arrived: the three form notifications, Ninja Forms' confirmation to the visitor, and two plain test emails. Every one came from the site's address, and the form notifications carried the visitor's address in Reply-To, so hitting Reply still answers the customer.
On your own site you need a real account to send through. That can be the mailbox you already have on your domain, at Google Workspace, Microsoft 365 or your host, or a sending service. The From address should be that account's address, or another one on the same domain. Switch on the plugin's option to force it, otherwise a form plugin can still put some other address in From. Then send the plugin's test email before you touch the form again. A failed test prints the error that matters. A test that arrives while the form stays silent sends you back to the form's notification settings.
Our test server accepted every email it was given, so this proves WordPress now hands the email to a mail server. Whether Gmail or Outlook then accepts it depends on the next section.
WordPress sent it, but it never arrived
When the log says the email was handed over and your inbox stays empty, the email left WordPress and was refused, quarantined or filed as spam somewhere after that. WordPress never hears about it. Contact Form 7's “It has been sent” and the other plugins' thank-you messages mean only that this hand-off worked.
A common cause is the From address. Many tutorials tell you to put the visitor's email there so you can hit Reply. Then your server sends mail claiming to be from Yahoo or iCloud, and those domains publish a DMARC policy telling every receiver what to do with mail that uses their name without their permission. Contact Form 7 warns about this in its own editor: with the visitor's address in From, it showed “Sender email address does not belong to the site domain.”
| Visitor's address ends in | Policy | What it asks receivers to do |
|---|---|---|
| yahoo.com | p=reject | Refuse the message |
| aol.com | p=reject | Refuse the message |
| icloud.com | p=quarantine | Treat it as suspicious, usually spam |
| gmail.com | p=none, sp=quarantine | No instruction for gmail.com itself; the receiver decides |
| outlook.com, hotmail.com | p=none | No instruction; the receiver decides |
So a form that sends “From: someone@yahoo.com” asks the receiving server to refuse its own notification. Put an address on your site's domain in From and the visitor's address in Reply-To, in every form and in the SMTP plugin. WordPress's own default, which we saw as wordpress@olive-bakery.test, is already on your domain. The question then is whether your domain allows the server that sends it, which is what SPF and DKIM records say. A mail account or sending service gives you the exact records to add; our guide to contact form emails going to spam walks through them.
Before you change DNS, look properly in the receiving mailbox. Check the spam folder and any filters, and on Google Workspace or Microsoft 365, the quarantine in the admin console, which is separate from the spam folder. And reread the To address in the form's settings: a notification can go to an old address, or to whoever built the site years ago.
Contact Form 7, WPForms and Elementor
All three plugins we tested send through WordPress, so the checks above apply to each of them. Where they differ is in what they tell the visitor and what they keep.
Contact Form 7 is the one that tells the visitor when sending fails, with a red border around the error. The same sentence with an orange border means a spam check stopped the message, and then no email is attempted at all. It keeps no copy of messages, so install Flamingo, its companion plugin, before you start testing. Our Contact Form 7 error guide goes through each colour.
WPForms Lite thanked our visitor and kept no entry, so when its email fails, the message is gone. Open the form's Settings → Notifications and check the Send To address. While you debug, also switch off “Optimize Email Sending” in WPForms' email settings. It queues emails to go out later, and you want each test to send right away. The rest is in our WPForms guide.
Elementor's Form Lite widget, from the Hello Plus add-on, showed two error sentences at once when mail failed, and without Elementor Pro it saved nothing. See our Elementor form guide. We haven't tested Gravity Forms or Divi's contact module for this article, so we won't guess how they report a failure; the mail log above will show you either way.
Ninja Forms not sending email
Ninja Forms is the one most likely to fool you, because its default success message promises an email. The default “Contact Me” form says “Form submitted successfully. A confirmation email was sent to” the visitor's address, and it said that on our test server while both of its emails failed. The plugin knew it had failed, because the reply it sent to the browser listed the email action with "sent": false. To see that on your site, open the browser's Network tab, submit the form and click the admin-ajax.php request; the answer is under data → actions → email.
Your message is probably still there, though. Ninja Forms saved our submission even though no email left, so look under Ninja Forms → Submissions and pick the form. If your messages are there, only the email is broken, and the steps above fix it. If they aren't, check that the form still has its “Record Submission” action under Emails & Actions, then go back to the first step: the submission may not be reaching WordPress.
The default form has two email actions, and both are on. One sends a confirmation to the visitor, using the form's email field. The other notifies you at {system:admin_email}, which is the address under Settings → General in WordPress, so a stale admin address there means your notifications go somewhere you don't read. Open each action under Emails & Actions and check the To field, keep From on your own domain and make sure Reply-To on the notification is {field:email}, as it is in the default form. With an SMTP plugin set up, as described above, our test form's email action changed to "sent": true and both emails arrived.
When the email works again, edit that success message anyway. It lives in the form's Success Message action, and on our test site it promised Emily an email she never got.
If you'd rather not depend on WordPress mail
Every fix above is about getting your WordPress server, or an account it logs in to, trusted by Gmail and Outlook. If the contact form is the only thing on the site that sends email, you can take that part out. With Formgong, the form posts its data to Formgong instead of to WordPress, so delivery doesn't depend on your host's mail, an SMTP plugin or its password. Every submission is kept in an inbox you can search, and then sent to you by email and, if you like, to Telegram, so a filtered email no longer means a lost message. The Formgong plugin for WordPress adds a form block and a shortcode, and a plain HTML form works as well; our guide to a WordPress contact form without a plugin has the steps.
Keeping your current plugin is fine as well. Once SMTP is set up, send yourself a test from the live page now and then, because a changed mailbox password or a site move breaks it without any warning on the form. Forms outside WordPress have their own guide, contact form not sending email.
Where did yours stop?
Which plugin was it, and where did the email stop? Write to support@formgong.com with what the form showed and the line from your mail log. When it's a case we haven't seen, we set it up on a test site and add what we find to this page.
Frequently asked questions
Why is my WordPress contact form not sending email?
Usually the form works and the email fails. Form plugins hand the email to WordPress's wp_mail(), which uses the server's PHP mail() unless an SMTP plugin is set up, and some hosts limit or switch that off. If mail does leave, a From address that isn't on your domain gets it refused or sent to spam.
How do I test if WordPress can send email without a plugin?
Use “Lost your password?” on wp-login.php. If WordPress cannot send, the page says “The email could not be sent. Your site may not be correctly configured to send emails.” For the exact reason, log the wp_mail_failed hook from a small file in wp-content/mu-plugins.
Why does Ninja Forms say a confirmation email was sent when nothing arrives?
Because that sentence is the form's default success message, and Ninja Forms shows it whether or not the email went out. We saw it while both emails failed; the response in the browser said "sent": false for the email action. The message itself was saved under Ninja Forms → Submissions.
Do I need an SMTP plugin for WordPress contact form emails?
If the mail log or the lost-password test shows WordPress can't send, yes. WP Mail SMTP, FluentSMTP or Post SMTP make WordPress log in to a mail account instead of calling the server's mail(). On our broken test server, adding one made all six emails arrive without touching a form.
Are my form messages lost when the email fails?
It depends on the plugin. In our test Ninja Forms kept the message under Submissions, while Contact Form 7 and WPForms Lite kept no copy, so the failed email was the only one. Contact Form 7 can keep copies with its companion plugin Flamingo.
Sources and documentation
Official references for this guide: Formgong: Contact Form 7 “There was an error trying to send your message”, Formgong: PHP mail() not sending email, Formgong: WordPress contact form without a plugin. WordPress, where data is stored.
Related guides
- Lovable form submissions to email and Telegram
- HTML contact form without a backend: a working example
- How to send website form submissions to Telegram
- Contact form not sending email? Check where it stops
- Managing website leads in Telegram without a CRM
- Form backend for Lovable, Bolt, v0, Cursor
- Telegram bot for a contact form: build or skip?
- GDPR form backend: 7 checks before you choose
- Lovable form not sending email? 6 fixes
- Netlify Forms not working? React and Bolt fixes
- Stop contact form spam without a CAPTCHA
- GitHub Pages contact form: a working setup
- Mailto Form in HTML: Why It Fails and What to Use
- HTML form to Google Sheets: 2 free methods
- Webflow form submission limit: what to do at 50
- Turnstile vs reCAPTCHA vs hCaptcha for forms
- Contact Form 7 and Elementor forms to Telegram
- Squarespace contact form not sending email?
- Shopify contact form: where do messages go?
- Google Form to Telegram: free Apps Script way
- Wix contact form not sending email? Fixes
- EU / GDPR Formspree alternatives compared
- HTML form action attribute explained
- How do HTML forms work? The HTTP request
- Types of Injection Attacks on Web Forms (2026)
- Indirect Prompt Injection in MCP
- MCP Rug Pull Attack: Detect Tool Changes
- Form without a backend: 7 ways that work
- Thank-you page after form submission (HTML)
- Indirect Prompt Injection Examples (2023–2026)
- Indirect Prompt Injection via Email
- What Is Tool Poisoning in MCP?
- WordPress contact form without a plugin
- Send email from frontend JavaScript
- How to Prevent Indirect Prompt Injection
- Honeypot Form Field: How to Add One That Works
- Contact Form with File Upload (HTML, No PHP)
- Angular contact form without a backend
- Send form submissions to Slack or Discord without Zapier
- Verify a form webhook signature (HMAC-SHA256)
- Contact forms that send nothing: 793 AI-built sites tested
- v0 contact form that actually sends: 3 ways
- How we tested AI-built contact forms, and 12 bugs we hit
- Cloudflare vs Netlify free plan: hosting that never pauses
- EmailJS 412 “Gmail_API: Invalid grant”: reconnect Gmail
- Resend “You can only send testing emails”: verify a domain
- Supabase Edge Function blocked by CORS policy: 3 causes
- Formspree “Form not found” and other errors: fixes
- Web3Forms errors: “Invalid access key” and 403 explained
- How to add customer reviews to your website for free
- Getform not working? “This form has been deleted” and more
- Next.js contact form not working? 6 errors, reproduced
- Webflow form not sending email? What to check, tested
- FormSubmit not working? “This form needs Activation” fix
- Contact form “TypeError: Failed to fetch”: causes and fixes
- WooCommerce product enquiry form
- Contact Form 7 vs WPForms
- Gravity Forms alternative free
- WordPress contact form block
- 535-5.7.8 Username and Password not accepted (Gmail)
- 535 5.7.3 Authentication unsuccessful: Office 365 SMTP
- Nodemailer “Missing credentials for "PLAIN"”: the fix
- Nodemailer “Greeting never received”: port 465 fix
- Nodemailer SSL “wrong version number”: the port fix
- Nodemailer “self-signed certificate in certificate chain”
- Nodemailer ECONNREFUSED 127.0.0.1:587: missing SMTP host
- SendGrid “authorization grant is invalid”: 401 fix
- Mailgun 401 Forbidden: why the API rejects your key
- “Edge Function returned a non-2xx status code”: the fix
- Next.js “Body exceeded 1 MB limit”: Server Action fix
- Unexpected token '<', "<!DOCTYPE "... is not valid JSON
- “TypeError: Body is unusable”: body has already been read
- Turnstile “timeout-or-duplicate” and other siteverify errors
- Turnstile vs hCaptcha vs reCAPTCHA: speed and size tested
- Judge.me reviews not showing on Shopify: how to fix it
- Judge.me review carousel not showing: how to fix it
- Yotpo reviews not showing on Shopify? Check the app embed
- Loox reviews not showing on product page: how to fix
- Shopify reviews not showing: what to check first
- How to show reviews on Shopify
- GDPR for website forms: what each type of form needs
- WooCommerce reviews not showing: how to fix it
- Stamped.io reviews not showing on Shopify: how to fix it
- Etsy reviews not showing: why and what to do
- Trustpilot widget not loading: how to fix TrustBox
- Yotpo problems in 2026: what merchants report
- Contact Form 7 “error trying to send your message” fix
- Elementor form “Your submission failed because of an error”
- Framer form not sending email or not working: what to check
- Carrd contact form not working: plans, spam and errors
- Google review link not working: what customers see and why
- tawk.to widget not showing on your website: causes and fixes
- How to add questions and answers to your product page
- “Failed to send a request to the Edge Function”: fixes
- Next.js “Failed to find Server Action”: what it means
- Brevo “unauthorized: Key not found” 401: the fix
- Amazon SES “Email address is not verified”: the fix
- Shopify contact form not working: how to fix it
- Judge.me alternative for WooCommerce after the 2025 shutdown
- Free WooCommerce review plugins compared on the free version
- WooCommerce review reminder emails without a paid plugin
- Add Voice Recording to a Website Form
- Contact Form 7 spam: how to stop it
- WPForms not sending email: how to fix it
- Contact form emails going to spam: how to fix it
- HTML form not submitting: how to fix it
- Contact form not working: how to find the fault
- Webflow form spam: how to stop it
- Website form to Notion: how to set it up
- Website form to WhatsApp: what works and what does not
- What 1-star reviews say about AI support chatbots
- Which free form backend gives you the most submissions?
- Elfsight reviews widget not showing? Check the view limit
- Next.js contact form backend vs Server Actions
- Review stars not showing in Google search results
- How to stop duplicate form submissions
- How to see which form leads came from ChatGPT
- What happens when a form webhook fails
- When to send a review request email after an order
- How to collect video testimonials for free
- Add contact form sign-ups to Mailchimp or Klaviyo
- How to migrate from Formspree without losing submissions
- How to get a Google review link for your business
- What is a headless form backend?
- Is it safe to put a form access key in your HTML?
- AI chatbot that answers only from your website
- Minified React error #441 in Next.js
- Squarespace product reviews after Judge.me
- Accessible contact form checklist for WCAG 2.2
- How to ask a client for a testimonial by email
- How to respond to negative reviews, with examples
- 429 Too Many Requests on a contact form
- MCP server for forms in Cursor and Claude
- Can you offer a discount for a review?
- Do EU stores have to say if reviews are verified?
- Webflow form backend options compared
- How to add review schema JSON-LD to a product page
- How to turn a customer review into an Instagram post
- How to make a QR code for Google reviews
- Live chat or chatbot for a small business website
- Why people abandon your contact form halfway
- Which form backend do AI assistants pick? 54 answers
- PHP mail() not sending email, even when it returns true
- What “Failed to fetch” means, tested in three browsers
- 405 Method Not Allowed when you submit a form
- Send a contact form to more than one email address
- What is review syndication, and who needs it?
- How to save HTML form data to a database
- NetworkError when attempting to fetch resource
- Send product reviews to Google Merchant Center
- PHPMailer not working on a live server
- AI review reply generator: does it help?
- React 19 contact form with useActionState
- Astro Actions or a form backend?
- Is no-reply@wixsiteautomations.com legit?
- Where to find the Judge.me review widget code
- AI review summaries: what shoppers actually see
- Photo reviews for WooCommerce, and the GPS inside them
- Review request email templates you can copy
- Reviews in AI search: what ChatGPT and Perplexity cite
- Lead capture form with UTM tracking, built and tested
- Form design best practices, with our own form data
- Client intake form template with file upload
- What is social proof? Meaning and examples
- What is user-generated content (UGC)?
- Benefits of negative reviews for your store
- How to get your first reviews as a new store
- How to use customer reviews in your marketing
- How to get more customer reviews
- React form validation without a library, tested
- jQuery submit form with validation
- reCAPTCHA v3 setup with the server score check
- Shopify social proof that shoppers can check
- HTML file input: accept, multiple, capture and size checks
- How to add hCaptcha to a form, with the server check
- How to add invisible reCAPTCHA to a form
- Bug report form template with browser details
- What the FTC fake reviews rule bans for online stores
- How to show reviews on your homepage
- Do reviews increase sales? What the studies show
- HTML input types and what each one sends
- HTML textarea, tested in a real form
- HTML dropdown menu in a form, tested
- Do reviews help SEO? What Google says and shows
- How to add a review carousel people can read
- Product review examples that help shoppers decide
- Which trust badges actually mean something
- Customer satisfaction survey with CSAT and NPS
- JavaScript FormData and what fetch actually sends
- JavaScript form validation without a library
- Server-side form validation and what it catches
- Email validation in JavaScript, tested on 33 addresses
- Zod form validation with FormData, tested
- Store reviews vs product reviews
- How to send review requests through Klaviyo
- How to tag customer reviews by topic and mood
- Custom review form questions worth asking
- Online reputation management for small businesses
- HTML radio button groups and what they send
- HTML label tag and what screen readers hear
- HTML autocomplete attribute, tested with Chrome autofill
- HTML fieldset and legend, and what disabled leaves out
- HTML button tag and what a form button sends
- Vite contact form that still works after the build
- How to test a contact form, end to end
- How to embed a Google Form, and what it loads
- Customer feedback questions that get real answers
- How to convert a file to base64 in JavaScript
- FilePond with a form backend, and when to skip it
- Bootstrap form validation and server errors
- Tailwind form validation, tested in three browsers
- Donation form in HTML, and where the payment goes
- How to ask for a review in person or by text
- Which review sites matter for your business
- What are customer reviews, and which kinds count
- Online review statistics, checked at the source
- Best review app for Shopify and WooCommerce
- Why Gmail sends your self-hosted mail to spam
- htmx contact form that sends to another domain
- AI form builders tested, from prompt to sent form
- Headless WordPress forms with Contact Form 7, tested
- React Hook Form watch vs useWatch, and what gets sent
- Elfsight widget not working? It vanishes when views run out
- Jotform not sending emails? Check Jotform's bounce list
- Typeform not working? A white box means a blocked script
- Positive review response examples that don't sound copied
- How to remove a Google review when you can't delete it
- Google reviews not showing up? 8 causes to check in order
- Is buying Google reviews illegal? Even a review swap counts
- Which reviews can you hide? A review moderation checklist
- Average star rating: what 4.8 from 5 reviews means
- Reviews on a product page: where and how many to show
- SaaS testimonials: 3 of 27 had a number in them
- Do reviews reduce returns? Not when they're too good
- Testimonial examples for business: what makes one believable
- Testimonial questions to ask clients, by type of business
- Testimonial page design: a page or a section?
- Testimonial advertising rules: what the FTC requires
- Form submission canceled because the form is not connected
- Input type date format dd/mm/yyyy: what you can change
- How to disable textarea resize, or allow only vertical
- How to prevent Enter from submitting a form
- form.submit() vs requestSubmit(): what submit() skips
- Custom HTML checkbox CSS that doesn't break required
- How to reset a form after submit, and what reset() keeps
- Input type number maxlength not working? What to use
- How to create an HTML form, step by step
- Best form builder: free plans and branding, checked
- Best WordPress contact form plugin: 10 free ones compared
- How to increase form conversion rate: start with the count
- Form backend vs form builder: which one do you need?
- Contact Form 7 webhook? Turning it on switched our email off
- Gravity Forms webhook: what it sends and the URLs it rejects