How to Add a Contact Form in WordPress
Building the form takes five minutes. Making sure every submission reaches a person — sender address, SMTP, stored entries, spam protection, a real test — is the part that matters.
Some links on this page are affiliate links: if you buy through one, we may earn a commission at no extra cost to you. It does not change what we recommend; see the editorial policy.
The short version: install a form plugin, build a form with name, email and message, place it on a Contact page with the plugin's block or shortcode, then set the notification From address to your own domain, configure SMTP and send a test from a private window — the last three steps are where contact forms actually fail.
Creating the form is the quick part. Making sure every submission reaches a person is what this guide is really about.
Step 1: choose how the form is built
WordPress core has no form that processes submissions, so you need one of these:
| Option | Good for | Trade-off |
|---|---|---|
| Form plugin | Most sites | One more plugin to maintain |
| Page builder form widget | Sites already built in Elementor Pro or similar | Tied to the builder |
| Embedded hosted form | Surveys, internal forms | Data and styling live elsewhere, see embedding a Google Form |
For a contact form, a plugin is the default. Pick one that stores entries, not only emails them — the comparison is in choosing a contact form plugin. The free Contact Form 7 is light but needs a companion plugin for storage; WPForms has a drag-and-drop builder whose free Lite version sends notifications, with stored entries in the paid tiers.
Step 2: build the fields
Keep it short. Every extra field costs submissions.
- Name — one field, not first and last, unless you genuinely need them apart.
- Email — required, with the field type set to email so it is validated.
- Message — a paragraph field, required.
- Phone or subject — only if you will use them.
- Consent checkbox — only if you will add the person to a mailing list; replying to an enquiry does not need one.
Give every field a visible label, not just placeholder text that disappears when someone starts typing.
Step 3: place the form on a page
Create a page called Contact and insert the form in one of three ways:
- Block. Most form plugins add a block to the editor. Search for the plugin's name, insert it and choose the form.
- Shortcode. Copy the shortcode from the plugin's form list and paste it into a Shortcode block. How shortcodes work is in WordPress shortcodes explained.
- Widget. For a sidebar or footer form, add the block or shortcode in the widget area — see WordPress widgets — or, in a block theme, in the footer template part via the Site Editor.
Shortcodes look like this; the ID comes from your own form list:
[contact-form-7 id="1a2b3c4" title="Contact form 1"]
[wpforms id="123"]
To output a form from a theme template instead, wrap the shortcode:
<?php echo do_shortcode( '[wpforms id="123"]' ); ?>
Add the Contact page to the main menu and the footer.
Step 4: configure the notification
This is the step that decides whether the email arrives.
- Send To: a monitored mailbox, ideally a shared address rather than one person's inbox.
- From Email: an address on your own domain, such as
forms@yourdomain.com. Never the visitor's address — mail claiming to come from someone's Gmail but sent by your server fails authentication and is rejected or filtered. - Reply-To: the visitor's email field, so pressing Reply answers them.
- Subject: something you can filter on, such as "Website enquiry".
Step 5: set up SMTP
By default WordPress sends mail through the server's PHP mail function, which many hosts restrict and receiving servers distrust. Connect the site to an authenticated mail service with an SMTP plugin and add the SPF and DKIM records it asks for. The full procedure is in WordPress not sending emails.
Step 6: turn on entry storage
Stored entries mean a failed email is an inconvenience, not a lost customer. Turn storage on, set a retention period, and mention it in your privacy notice per WordPress GDPR compliance.
Step 7: add spam protection
Start with the plugin's honeypot, which stops much automated spam with no friction for visitors. Add a captcha only if spam continues — the options are in adding reCAPTCHA to a form. One defence, tuned, beats three stacked.
Step 8: set the confirmation
Show a clear message after submission — "Thanks, we reply within one working day" — or redirect to a thank-you page. A form that silently reloads leads to duplicate submissions.
If the page is cached, exclude it from full-page caching: a cached security token causes submissions to fail for some visitors.
Common mistakes
- From address set to the visitor's email. The most common reason notifications vanish.
- Testing only while logged in on your own computer.
- No storage, so nothing records the enquiries that never arrived.
- Notifications to an address nobody reads, such as the original developer's.
- Placeholder-only fields, which fail accessibility and confuse visitors.
Verify
Log out, open a private window on a phone using mobile data, and submit the form. Then check:
- The confirmation message appears.
- The entry is stored in the dashboard.
- The notification arrives at an external mailbox, in the inbox rather than spam.
- Replying goes to the address you entered on the form.
If the entry exists but the email does not, it is a mail problem — follow contact form not sending email. Repeat this test after plugin updates and after any host migration.
Frequently asked
- Not a working one in core WordPress — there is no built-in form that processes submissions. Your options are a form plugin, the form widget of a page builder you already use, or a hosted form embedded in the page.
- The form worked; the mail did not. Usually the From address is not on your domain or the site sends through unauthenticated PHP mail. Set the From address to your domain, configure SMTP, and turn on entry storage so nothing is lost meanwhile.
- On a dedicated Contact page linked from the main navigation and footer. A form in a sidebar or footer on every page also works, but it loads the form's assets sitewide, so keep it to sites where enquiries really come from every page.