HTML Contact Form Template That Emails You (Copy and Paste)
Three copy-paste HTML contact form templates that send submissions to your email: minimal, full with spam protection, and one with file upload. No PHP, no SMTP, works on any host.
The ShipMyForm team
· 3 min read
Three HTML contact form templates you can paste into any page, each wired to
email you. They post to a form endpoint, so there is no PHP file, no SMTP
setup and no JavaScript required. Replace YOUR_FORM_ID with your own, set
the address that should receive submissions, and the form is live.
Full disclosure: ShipMyForm is our product and provides the endpoint in these templates. The markup itself is plain HTML that works with any endpoint that accepts a form POST.
Before you paste: the one thing to change
Every template has this line:
<form action="https://shipmyform.com/f/YOUR_FORM_ID" method="POST">YOUR_FORM_ID comes from creating a form, which takes about a minute and is
free. The endpoint receives the submission, stores it, filters spam, and emails
it to the address you set. If you want to know why the form cannot simply email
you by itself, how to send an HTML form to email
explains the mechanics.
Template 1: the minimal email form
Two fields. Right for a footer, a sidebar, or a "questions?" box.
<form action="https://shipmyform.com/f/YOUR_FORM_ID" method="POST" class="smf-form">
<label>
Your email
<input type="email" name="email" autocomplete="email" required />
</label>
<label>
Message
<textarea name="message" rows="4" required></textarea>
</label>
<button type="submit">Send</button>
</form>The visitor's email becomes the Reply-To of the notification, so replying
from your inbox reaches them.
Template 2: the full contact form with spam protection
Name, email, subject line, message, a honeypot field, and a subject for the email you receive. This is the one most sites want.
<form action="https://shipmyform.com/f/YOUR_FORM_ID" method="POST" class="smf-form">
<!-- Subject line of the email you receive -->
<input type="hidden" name="_subject" value="New message from the contact form" />
<label>
Name
<input type="text" name="name" autocomplete="name" required />
</label>
<label>
Email
<input type="email" name="email" autocomplete="email" required />
</label>
<label>
Subject
<input type="text" name="subject" maxlength="120" />
</label>
<label>
Message
<textarea name="message" rows="6" required></textarea>
</label>
<!-- Honeypot: hidden from people, filled in by bots. Leave it empty. -->
<input type="text" name="_gotcha" tabindex="-1" autocomplete="off"
aria-hidden="true" style="position:absolute;left:-9999px" />
<button type="submit">Send message</button>
</form>Three details worth keeping:
autocompletetokens let browsers and password managers fill the form in one tap, and they satisfy an accessibility requirement outright.- The honeypot is a hidden text field. Real visitors never see it, so it stays empty; bots fill every field, so theirs gets rejected. No CAPTCHA needed for most spam. The full spam setup adds rate limiting and server-side classification.
_subjectsets the subject of the email you receive, which is how you tell messages from different forms apart in your inbox.
Template 3: contact form with file upload
For quote requests, job applications, or support forms where an attachment
helps. The form needs enctype="multipart/form-data", and file uploads are a
paid-plan feature on most backends, including ours.
<form action="https://shipmyform.com/f/YOUR_FORM_ID" method="POST"
enctype="multipart/form-data" class="smf-form">
<input type="hidden" name="_subject" value="New quote request" />
<label>
Name
<input type="text" name="name" autocomplete="name" required />
</label>
<label>
Email
<input type="email" name="email" autocomplete="email" required />
</label>
<label>
Tell us about the job
<textarea name="message" rows="5" required></textarea>
</label>
<label>
Photos or documents
<input type="file" name="attachment" accept="image/*,.pdf" multiple />
</label>
<input type="text" name="_gotcha" tabindex="-1" autocomplete="off"
aria-hidden="true" style="position:absolute;left:-9999px" />
<button type="submit">Request a quote</button>
</form>Attachments arrive as links in the notification email and are stored with the submission.
The styles
Each template uses the class smf-form and plain elements, so it inherits
your site's styles if you do nothing. If you want it to look finished
immediately, this block is enough:
.smf-form { display: grid; gap: 14px; max-width: 480px; font: 15px/1.5 system-ui, sans-serif; }
.smf-form label { display: grid; gap: 6px; font-weight: 500; }
.smf-form input, .smf-form textarea {
font: inherit; padding: 10px 12px; border: 1px solid #d4d4d4; border-radius: 8px;
}
.smf-form input:focus, .smf-form textarea:focus { outline: 2px solid #111; outline-offset: 1px; }
.smf-form button {
font: inherit; font-weight: 600; padding: 11px 16px; border: 0; border-radius: 8px;
background: #111; color: #fff; cursor: pointer; justify-self: start;
}Want a different accent, dark mode, Tailwind classes, or React and Vue versions? The contact form generator builds all of these from the same fields.
What happens when someone submits
- The browser posts the fields to the endpoint. Nothing about email is in the page.
- The endpoint checks the honeypot, rate limits by IP, and runs spam classification.
- Clean submissions are stored and emailed to your notification address,
sent from an authenticated domain with the visitor as
Reply-To. - The visitor lands on a thank-you page: the hosted default, or a URL you set in the form's settings.
Step 3 is why these forms do not land in spam. The classic mistake is sending the notification as the visitor, which fails authentication for a domain you do not control. Why form emails go to spam covers it if you are fixing an existing setup.
Post the same form with fetch() and show an inline thanks. The
markup does not change; only a few lines of JavaScript are added. See
submit a form with fetch().
Customising the templates
- Add a field. Any input with a
nameis included in the email and the stored submission. No configuration needed. - Make something optional. Remove
required. - Restrict what is accepted. Add server-side rules in the form's settings,
so a
phonefield must look like a phone number or abudgetmust be a number. Validation rules return per-field errors tofetch()callers. - Redirect after submit. Set the redirect URL in settings. It has to be on one of the form's allowed domains.
- Restrict which sites can submit. Add your domain to allowed domains, so the endpoint refuses posts from anywhere else.
Next steps
- Why the form cannot email you by itself, and every method compared: HTML form to email
- Same form, no page reload: submit a form with fetch()
- Design it right: form UX best practices
- Start free: get your form ID, 100 submissions a month, no card.
Frequently asked questions
- Does this HTML form email me without PHP?
- Yes. The form posts to a form endpoint that sends the email server-side, so the page stays plain HTML and works on any host, including ones that cannot run PHP such as GitHub Pages, Netlify and Cloudflare Pages. Replace YOUR_FORM_ID with your own and set the notification address in the form's settings.
- Can I use this template with my own CSS?
- Yes. The markup uses plain elements and a few class names; delete the style block and it inherits your site's styles. The generator can also output the same form with Tailwind classes or no classes at all.
- How do I change the email subject?
- Add a hidden input named _subject with the subject you want. Anything in the form's fields is included in the email body, and the visitor's address becomes the Reply-To so hitting reply reaches them.
- How do I send people to my own thank-you page?
- Set the redirect URL in the form's settings, or add a hidden input named _redirect. The redirect must be on a domain in the form's allowed-domains list so nobody can abuse your form as an open redirect.
- Will the emails go to spam?
- Not when they are sent from an authenticated domain, which a form backend does for you. The classic cause of form mail in spam is sending the notification as the visitor, which fails SPF and DMARC. The templates here never do that.
- Do I need the honeypot field?
- Keep it. It is a hidden field real people never fill in and bots almost always do, and it costs your visitors nothing. Combined with the endpoint's server-side filtering it stops most spam without a CAPTCHA.
Related guides
How to Send an HTML Form to Your Email (Without PHP or SMTP)
Every way to get HTML form submissions into your inbox, compared: mailto:, PHP mail(), JavaScript email services, serverless functions, and a form backend. Plus the deliverability part every tutorial skips.
How to Submit a Form with JavaScript fetch() (and Send It to Your Email)
The vanilla-JS pattern for submitting a form without a page reload — intercept submit, fetch() the data, and render success and per-field errors from the JSON response.
Why Your Contact Form Emails Land in Spam (and How to Fix It)
Most form notifications land in spam for one reason: the From address is the person who filled the form. Here's why that fails authentication, and what to send instead.