Customer contact · How-to
How to add a contact form to a static website
A static site is just files. There's no server to receive a form and send you an email, so the message has to go somewhere else. Here are your options, from the simplest to the most work.
Why a plain HTML form doesn't work
An HTML form sends its data to a URL in its action. On a static host like GitHub Pages, Netlify, Cloudflare Pages or a plain file bucket, nothing at that URL can read the message. You need a service, or your own small server, to receive it.
Option 1: a mailto link
<a href="mailto:hello@yourproduct.com">Email us</a>
It works everywhere and costs nothing. But it opens the visitor's mail app, which many people don't have set up, especially on a work computer. And your address sits in the page, where spam bots will find it. Fine for a personal site, weak for a product.
Option 2: your host's form feature
Some hosts can catch form posts for you. Netlify, for example, has form handling built in. If you already host there, it's a quick start. The catch: you're tied to that host, and messages live in its dashboard next to your deploys, not with the rest of your support.
Option 3: a form backend service
These services give you a URL to put in the form's action, then forward each message to your email. Formspree, Web3Forms and Getform work this way. You write the HTML and style it yourself:
<form action="https://forms.example.com/your-form-id" method="POST"> <input type="email" name="email" required> <textarea name="message" required></textarea> <button>Send</button> </form>
Good if you want full control of the markup. Check the free plan limits and how the service deals with spam.
Option 4: an embedded form
A script draws the whole form for you: the fields, error messages and the “sent” state. It sends the message to an inbox. You paste two lines where the form should appear. Less control over the markup, but less to get wrong.
That's how MVPKit's form works:
<div id="mvpkit-contact"></div> <script src="https://mvpkit.net/embed/contact.js" data-project="YOUR_PROJECT_ID" async></script>
Messages land in your project's inbox, and you get an email when a new one arrives.
Option 5: a small serverless function
If you like writing code, a function on Cloudflare Workers, Vercel or AWS Lambda can take the post and send an email through a mail API. You get full control, but you also own spam protection, rate limits, email delivery and error handling. For most product sites, that's more work than the form is worth.
What to test, whichever you pick
- Send a real message from a private browser window, and one from your phone.
- Check that it arrives somewhere you actually look every day.
- Try an empty message and a broken email address. The error should be clear.
- After sending, the visitor should see a clear “Sent” message.
- Plan for spam from day one. Here's how to stop it without a CAPTCHA.
Quick rule: If you expect a few messages a week, a form service or an embed is plenty. Build your own only if the form is part of your product.
MVPKit's form works on any static site: plain HTML, Hugo, Jekyll, Astro, a static Next.js export, GitHub Pages. Each project also gets a public contact page, so you can just link to it if you'd rather not put a form on your site. Messages from all your projects show up in one account.
Want a contact form without building a backend? See how MVPKit does it.