Skip to content

How to add a contact form to WordPress

Adding a contact form to WordPress takes a plugin, a page and a few minutes. Making sure every message reaches you is the real job, because the form can say “sent” while your inbox never gets the email. Set the sender address correctly, send through authenticated SMTP, store every entry, and test from outside your own login.

On this page
  1. What do you need before you start?
  2. Which form plugin should you use?
  3. How to add the form, step by step
  4. Why does the form say “sent” when no email arrives?
  5. How do you test a contact form properly?
  6. Why should submissions be stored in WordPress?
  7. How do you keep spam out without blocking real enquiries?
  8. What to do if the form still isn’t working
  9. When is a plugin form not enough?
  10. Frequently asked questions

Key takeaways

  • Contact Form 7’s FAQ says its green success message only means the PHP mail function finished. It does not mean the email was delivered.
  • Send from an address on your own domain and put the visitor’s address in Reply-To. A visitor’s Gmail address in the From field is a common reason messages end up in spam.
  • Store submissions in WordPress with Flamingo, CFDB7 or your builder’s entries screen, so a mail failure delays a lead and doesn’t lose it.
  • In Contact Form 7, a red border around the error means the mail failed and an orange border means a spam filter flagged the message. The error text is the same for both.
  • Check SMTP and your SPF, DKIM and DMARC records before you switch plugins. A new form builder sends mail the same way and won’t fix them.

Contact Form 7’s own FAQ says the green “Thank you for your message. It has been sent.” response only means WordPress’s mail function finished running. It does not mean the email arrived. That gap is how small businesses end up with a contact form that looks fine for weeks and catches nothing.

Putting a form on a page is the easy half. This guide covers that half quickly, then spends most of its time on the parts that decide whether you ever read the message: the sender address, how the mail gets sent, where entries are stored, spam, and testing.

What do you need before you start?

You need administrator access to a self-hosted WordPress site, an email address on your own domain (such as hello@yourbusiness.com), and a way to change your domain’s DNS records, or the name of whoever can. Most delivery problems get fixed in DNS and mail settings, not inside the form.

If your site runs on WordPress.com rather than your own hosting, it has its own Form block and its own rules about plugins, so some of these steps will look different.

Which form plugin should you use?

Pick the simplest tool that does what you need. WordPress doesn’t ship a contact form in core, and themes usually style forms without creating them, so you will be installing a plugin.

Contact Form 7 is free and shows 10+ million active installs on WordPress.org. You build forms by editing short tags rather than dragging fields around, and it doesn’t save submissions unless you add a plugin for that. It’s a good fit for a plain name, email and message form if you’re happy reading settings carefully.

Drag-and-drop builders such as WPForms Lite (5+ million active installs), Fluent Forms, Forminator and Ninja Forms are easier for a non-developer to check. Some keep entries and integrations behind a paid tier, so look at the free feature list for the things you need, like a phone field or saved entries, before you commit.

Whichever you choose, check its last update date, tested-up-to version and PHP requirement before you click Install. Our guide to installing a WordPress plugin safely covers what to look for on the listing.

How to add the form, step by step

The steps below use Contact Form 7 as the example. Other builders use different screen names for the same steps.

  1. Install the plugin. Go to Plugins, then Add New, search for the plugin, click Install Now, then Activate.
  2. Build the form. Open Contact, then Contact Forms. The default form already has name, email, subject and message. Keep it close to that. Each extra field is one more reason for a visitor to give up. Make the phone field optional if you add one. If enquiries go to different people, a drop-down list of topics is easier to route than free text.
  3. Label every field. The W3C’s accessibility tutorial says each field needs a proper <label>, and placeholder text alone isn’t a reliable substitute. Placeholder text disappears as soon as someone starts typing. A label stays put.
  4. Set up the Mail tab. This is where most forms go wrong. See the next section.
  5. Put the form on a page. Go to Pages, then Add New (or open your existing Contact page), insert the Contact Form 7 block and choose your form. A shortcode in a Shortcode block works too.
  6. Publish, then test it as a stranger would. The testing section below explains how.

How should the Mail tab be filled in?

Contact Form 7’s mail documentation says the From address should be on the same domain as the website, and its best-practice guide says to put the visitor’s address in Reply-To instead. Your domain can’t legitimately send mail as someone’s Gmail account, and receiving servers know that.

To:       you@yourbusiness.com
From:     Website <hello@yourbusiness.com>
Subject:  New enquiry from [your-name]
Additional headers:
Reply-To: [your-email]

Message body:
From: [your-name] <[your-email]>
Subject: [your-subject]

[your-message]

Each word in square brackets is a mail-tag. It must match a field name in the form exactly. If you rename your-message in the form and forget to update the template, the email arrives with that field missing or with the raw tag in it. With Reply-To set, you can hit reply in your inbox and reach the visitor directly.

Contact Form 7 Mail tab with From on the site domain and Reply-To set to the visitor's email mail-tag
Using a domain-based address in the From field while placing the visitor’s email tag in the Reply-To header prevents deliverability issues without losing the sender’s reply address. · Source: contactform7.com

Why does the form say “sent” when no email arrives?

Because sending the email and receiving it are two separate steps. SiteGround’s knowledge base says WordPress commonly sends through PHP’s mail() function by default, and some mail providers mark those messages as spam. The form finishes its job and shows success. Then the message gets dropped, filtered or quarantined somewhere you can’t see.

The usual fix has three parts:

  • Send through authenticated SMTP. Install an SMTP plugin such as WP Mail SMTP or FluentSMTP and connect it to your mail provider or a transactional mail service. Use the host, port, encryption and login details your provider gives you. Port 587 with TLS and 465 with SSL are common, but your provider’s values are the ones that count. Wrong settings produce errors like “smtp connect() failed” or “535 Incorrect authentication data”.
  • Keep From on your domain. Use the same domain address as above, and make it match the account the SMTP plugin sends from.
  • Set up SPF, DKIM and DMARC. SPF lists the servers allowed to send for your domain, DKIM signs each message, and DMARC tells receiving servers what to do when those checks fail. Your mail provider publishes the exact records to add at your DNS host.

SMTP improves your chances. It doesn’t guarantee the inbox. A wordpress.org support thread from February 2026 makes the point that even an SMTP log saying “Success” only means the mail server accepted the message.

How do you test a contact form properly?

Don’t test while logged in as admin in the browser you built the form in. That session can hide caching and script problems your visitors will hit. Test like a stranger:

  • Submit from a phone on mobile data, logged out of WordPress.
  • Check that the email reaches the right inbox. Use an outside mailbox too, and look in its spam folder.
  • Hit reply and confirm the reply goes to the address you typed into the form.
  • Submit with a broken email address and an empty required field. The form should reject both, say what is wrong in words rather than colour alone, and keep what you already typed.
  • Complete the form once using only the keyboard, and once at phone width.

You’re done when a test from another device lands in the right inbox and you can reply to it. The success message doesn’t count.

Why should submissions be stored in WordPress?

Because email will fail eventually. A host changes something, a password expires or a DNS record gets edited. If every submission is also saved in your dashboard, a broken mail setup only delays your leads.

Contact Form 7 doesn’t store messages on its own. Flamingo, from the same developer, or CFDB7 saves them to the WordPress database, and CFDB7 can export them to CSV. Most drag-and-drop builders have an entries screen built in, though on some it’s a paid feature. Treat stored entries as untrusted input. Anyone can type anything into a public form.

How do you keep spam out without blocking real enquiries?

Stack quiet defences first and keep a CAPTCHA in reserve. A honeypot field catches bots that fill in every field, and Akismet screens message content. Rate limiting slows down repeat senders. Each CAPTCHA you show a bot is also shown to a customer on a phone, so add one only when the quiet layers aren’t enough.

Filters can go too far, too. In Contact Form 7, an orange border around the error means a spam check rejected the submission. The FAQ explains how to turn on spam logging, which tells you whether Akismet, reCAPTCHA or the disallowed list blocked it. Test the form again after changing any spam setting.

What to do if the form still isn’t working

Work out which step failed before you change anything. These causes are listed roughly in the order people run into them.

  1. Success message, no email. Mail delivery problem. Check whether the entry was stored, then go through SMTP, the From address and DNS as described above.
  2. Red border around the error. Contact Form 7 says this means the mail server couldn’t send. Its default message, “There was an error trying to send your message. Please try again later.”, appears for both mail failures and spam rejections, so read the border colour, not the words.
  3. Orange border. A spam check flagged the submission. Turn on spam logging to see which one.
  4. Email arrives with fields missing or showing [tags]. A mail-tag doesn’t match a field name. Line them up.
  5. The page shows [contact-form-7 404 "Not Found"]. The shortcode points to a form ID that no longer exists. Insert the form again with the block.
  6. The form won’t submit, or spins forever. Usually a conflict with another plugin, the theme, caching or a script. The Health Check plugin’s troubleshooting mode disables plugins and switches theme for your login only, so visitors see nothing change. Our guide to fixing plugins that stop working walks through the method.

Don’t swap form plugins as the first fix. In one r/Wordpress thread, the owner was told a new builder wouldn’t fix delivery, and the real fix turned out to be SPF and DMARC records set up during a call with their host. Sometimes switching does help when a theme conflict won’t go away, but try it after you’ve checked the mail settings, not before.

Stop and contact your host when the SMTP plugin’s test email fails with the correct details, or when messages leave the site and still never arrive. The host can read the mail server logs. You can’t.

Contact Form 7 error message with a coloured border on a WordPress contact form
Contact Form 7 uses distinct border colors for the same generic error text, separating spam detection in orange from outright mail delivery failures in red. · Source: contactform7.com

When is a plugin form not enough?

Off-the-shelf forms start to struggle with dynamic recipients (send to whichever branch the visitor picked), post data in the email (which property or product was this about), forms in several languages, CRM or webhook connections, and product enquiries in WooCommerce. WooCommerce’s own Product Enquiry Form extension is no longer available and won’t be updated.

You can build a form without a plugin, but you’d need more than HTML. You also need code that processes the submission, validates and sanitises every field, checks a nonce, filters spam and sends mail safely. That’s a development task. If you’d rather describe the form than build it, SiteSelf can write that code on your existing site through chat. That work is custom WordPress development and needs hosting access. Your DNS records and mail provider stay with you.

Frequently asked questions

Does WordPress have a built-in contact form?

Self-hosted WordPress doesn’t include one in core, so you add a plugin. WordPress.com is a separate hosted product with its own Form block. Some themes offer a form button that installs a plugin in the background.

Can I put the visitor’s email address in the From field?

No. Receiving servers see your website claiming to be someone’s Gmail or Outlook account and treat it as spoofing. Use an address on your own domain as From, and put the visitor’s address in Reply-To.

Where do contact form submissions go?

By default, only to the email address in the form’s To field. Contact Form 7 keeps no copy unless you add Flamingo or CFDB7. Many other builders save entries in the dashboard, sometimes only on paid plans.

Can I add the form inside a page builder or a theme template?

Most page builders have a shortcode widget that takes the form’s shortcode. In a PHP template file, Contact Form 7’s FAQ says to run the shortcode through apply_shortcodes(). Don’t put the form inside another <form> element.

Will updating the form plugin fix a broken form?

Only if the bug is in the plugin. Updates don’t fix mail or DNS. Check the Requires PHP and Requires WordPress lines on the plugin listing before updating, because an update your server can’t run swaps a broken form for a broken site.

Give your WordPress site its first task.

Connect the site you already have, add your agent to Slack or Telegram, and tell it what you need.

Connect your site

Start with 500 free credits. No credit card needed.