How to Add an HTML Contact Form to Any Website
Last updated: March 2026
Every website needs a contact form. A portfolio, a small business site, or a landing page all need a way for visitors to reach you. A simple HTML contact form is the most direct solution.
The problem? Plain HTML forms don't send emails on their own. You need a backend to process submissions and deliver them to your inbox. In this guide, you'll learn how to add a working HTML contact form for your website using plain HTML and a form backend service. The contact form code is ready to copy and paste. No server-side code, no PHP, no Node.js required.
What you need
- A website (static HTML, WordPress, Astro, Next.js, Carrd, anything)
- A free FormWit account
- 5 minutes
HTML form anatomy
Before jumping to code, here's what makes up an HTML contact form. Understanding each piece helps you customize it later.
The form element
The <form> tag wraps all your inputs. It has two critical attributes:
<form action="https://app.formwit.com/api/s/YOUR_FORM_ID" method="POST">
...
</form> action- the URL where the form data gets sent. For a form backend, this is the service's endpoint.method- alwaysPOSTfor contact forms.GETputs form data in the URL query string, which exposes it in browser history and server logs.
Labels and inputs
Each form field needs a <label> and an <input> (or <textarea>, or <select>). The label's for attribute must match the input's id:
<label for="email">Email</label>
<input type="email" id="email" name="email" required /> Three attributes matter on every input:
id- connects the label to the input for accessibility. Clicking the label focuses the input.name- the key used when the form data is submitted. If you forgetname, that field's data never reaches the backend.type- tells the browser what kind of input to render and what validation to apply.
The submit button
<button type="submit">Send</button> The type="submit" is technically the default, but being explicit is good practice. Avoid using <input type="submit">. A <button> element is more flexible because you can put HTML inside it (icons, spans for styling).
Input types relevant to contact forms
HTML5 provides input types that handle validation and mobile keyboard behavior for you. Here are the ones you'll use in contact forms:
type="text"
General purpose text input. Use for name, subject, company name, and any other free-text field.
<input type="text" name="name" required /> type="email"
Validates that the value looks like an email address (contains @, has a domain). On mobile, shows a keyboard with the @ symbol prominent.
<input type="email" name="email" required /> type="tel"
Shows a numeric keypad on mobile devices. Does not validate phone number format (phone formats vary too much internationally for a single regex to handle).
<input type="tel" name="phone" /> type="url"
Validates that the value is a URL. Mobile keyboards show "/" and ".com" keys. Useful for "Your website" fields.
<input type="url" name="website" placeholder="https://example.com" /> textarea
Multi-line text input for the message body. Not technically an <input> type, but essential for contact forms.
<textarea name="message" rows="5" required></textarea> The rows attribute sets the initial visible height. Users can resize vertically unless you set resize: none in CSS (don't do that, it's annoying).
select (dropdown)
Useful for subject/department selection when you want to route messages:
<label for="department">Department</label>
<select id="department" name="department" required>
<option value="">Choose one</option>
<option value="sales">Sales</option>
<option value="support">Support</option>
<option value="general">General inquiry</option>
</select> The empty first option with value="" combined with required forces the user to make a selection.
Hidden fields explained
Hidden fields submit data without showing anything to the user. They're useful for adding metadata to your form submissions.
<!-- Redirect after submission -->
<input type="hidden" name="redirect_to" value="https://yoursite.com/thank-you" />
<!-- Track which page the form was submitted from -->
<input type="hidden" name="source_page" value="pricing" />
<!-- Honeypot for spam (hidden via CSS, not type="hidden") -->
<input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off" /> Note the difference: the honeypot uses type="text" with style="display:none", not type="hidden". Most spam bots know to skip type="hidden" fields but will still fill in visible text inputs. Hiding the input with CSS tricks the bot into revealing itself.
FormWit recognizes two special hidden field names:
redirect_to- the URL to redirect to after submission_gotcha- honeypot field, submissions with a value here get rejected
All other hidden fields get included in the submission data and notification email, so you can use them to pass along context like page source, campaign ID, or plan selection.
Step 1: Create the HTML form
Start with a standard HTML form. Here's a contact form with name, email, and message fields:
<form action="https://app.formwit.com/api/s/YOUR_FORM_ID" method="POST">
<label for="name">Name</label>
<input type="text" id="name" name="name" required />
<label for="email">Email</label>
<input type="email" id="email" name="email" required />
<label for="message">Message</label>
<textarea id="message" name="message" required></textarea>
<button type="submit">Send</button>
</form> Replace YOUR_FORM_ID with the endpoint ID from your FormWit dashboard.
Step 2: Set up FormWit
- Create a free FormWit account
- Click Create Form in your dashboard
- Copy the form endpoint URL
- Paste it into the
actionattribute of your HTML form
That's it. When someone submits the form, FormWit receives the data, stores it in your dashboard, and sends you an email notification.
Step 3: Add spam protection
FormWit includes built-in spam filtering on every plan. For extra protection, add a honeypot field:
<input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off" /> Add this inside your form. FormWit automatically rejects any submission where this field has a value.
Form validation with HTML5 attributes
HTML5 provides built-in validation that works in all modern browsers without any JavaScript:
required
The browser prevents submission until the field has a value. The user sees a browser-native error message.
<input type="text" name="name" required /> type-based validation
type="email" checks for a valid email format. type="url" checks for a valid URL. The browser handles the validation and shows an error message if the format is wrong.
minlength and maxlength
Restrict the length of text input. Useful for preventing empty-looking submissions or absurdly long spam messages.
<textarea name="message" required minlength="10" maxlength="5000"></textarea> pattern
Validate against a regular expression. For example, requiring a phone number in a specific format:
<input type="tel" name="phone" pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
title="Format: 123-456-7890" /> The title attribute provides the error message shown when validation fails.
Combining validation attributes
Here's a fully-validated contact form using only HTML attributes:
<form action="https://app.formwit.com/api/s/YOUR_FORM_ID" method="POST">
<label for="name">Name</label>
<input type="text" id="name" name="name" required minlength="2" maxlength="100" />
<label for="email">Email</label>
<input type="email" id="email" name="email" required />
<label for="message">Message</label>
<textarea id="message" name="message" required minlength="10" maxlength="5000"></textarea>
<input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off" />
<button type="submit">Send Message</button>
</form> All validation happens in the browser before the form is submitted. No JavaScript needed.
Step 4: Style your form
The HTML form above is unstyled. Here's minimal CSS to make it look clean:
form {
max-width: 500px;
margin: 0 auto;
}
label {
display: block;
margin-bottom: 4px;
font-weight: 600;
}
input, textarea, select {
width: 100%;
padding: 10px;
margin-bottom: 16px;
border: 1px solid #ccc;
border-radius: 6px;
font-size: 16px;
font-family: inherit;
box-sizing: border-box;
}
input:focus, textarea:focus, select:focus {
outline: none;
border-color: #4f46e5;
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.15);
}
button {
background: #4f46e5;
color: white;
padding: 12px 24px;
border: none;
border-radius: 6px;
font-size: 16px;
cursor: pointer;
}
button:hover {
background: #4338ca;
} Two things to note: font-size: 16px on inputs prevents the auto-zoom behavior in iOS Safari. box-sizing: border-box ensures inputs with padding don't overflow their container.
Step 5: Add a custom redirect (optional)
By default, FormWit shows a "Thank you" page after submission. To redirect users to your own thank-you page, add a hidden redirect_to field:
<input type="hidden" name="redirect_to" value="https://yoursite.com/thank-you" /> The redirect_to value must be a valid http or https URL. It is stripped from the stored submission data and overrides any redirect URL configured in the dashboard.
Common pitfalls
- Missing
nameattributes: Every input needs anameattribute, or the data won't be submitted. Usename="email", not justid="email". - Using
GETinstead ofPOST: Always usemethod="POST"for contact forms. GET exposes form data in the URL. - Forgetting the
actionURL: Without theactionattribute pointing to your form backend, the form submits to your own page and nothing happens. - No validation: Add
requiredto mandatory fields and usetype="email"for email inputs so browsers validate before submission. - Duplicate
idattributes: If you have two forms on one page, each input'sidmust be unique across the entire page. Use prefixes likeid="contact-name"andid="newsletter-email". - Forgetting
for/idpairing: A<label>without a matchingforattribute doesn't connect to its input. Screen readers won't associate them, and clicking the label won't focus the input.
AJAX submission (optional)
If you want to submit the form without a page reload, use the Fetch API:
const form = document.querySelector('form');
form.addEventListener('submit', async (e) => {
e.preventDefault();
const data = new FormData(form);
const response = await fetch(form.action, {
method: 'POST',
body: data,
});
if (response.ok) {
alert('Message sent!');
form.reset();
} else {
alert('Something went wrong. Please try again.');
}
}); Summary
Adding an HTML contact form to any website takes a few minutes:
- Write the HTML form with
name,email, andmessagefields - Point the
actionattribute to your FormWit endpoint - Add a honeypot field for spam protection
- Use HTML5 validation attributes for client-side checks
- Style with CSS and optionally submit via AJAX
FormWit's free plan includes unlimited forms, 100 submissions per month, email notifications, and spam protection. Get started free.
Want to see how FormWit stacks up against other HTML form backends? Check our alternatives comparison for a full feature and pricing breakdown.
Related guides: Simple contact form · 5 ways to add a contact form · Send form submissions to email · Free contact form options · Spam protection methods · Copy-paste form templates
Frequently asked questions
What HTML do I need for a contact form?
At minimum: a <form> element with action and method="POST", input fields with name attributes for each piece of data you want to collect, and a submit button. Three fields (name, email, message) plus a honeypot for spam protection covers most use cases.
Do I need JavaScript for the form to work?
No. A plain HTML form with a method="POST" and action pointing to a form backend works without any JavaScript. The browser handles submission natively and redirects to a thank-you page. JavaScript is only needed if you want to submit without a page reload.
How do I add spam protection?
Add a hidden honeypot field: <input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off" />. Bots fill it in, humans never see it, and FormWit automatically rejects submissions where this field has a value. Combined with server-side rate limiting, this blocks most automated spam.
Want to skip the setup?
FormWit gives you a form endpoint in 60 seconds. Free plan, no credit card.
Need a form fast?
Build one visually with our free HTML form generator — no coding required.
Try the Form Generator →Connect your HTML form
Add a contact form to your site in 30 seconds. No backend code required.
Try FormWit Free