Static sites

A static site contact form in one attribute

Your static site doesn't need a backend, a serverless function, or a plugin to have a working contact form. Point a plain HTML form at an onsubmit.dev endpoint and every message lands in your inbox — the site itself needs nothing else.

The contact form is usually the only "dynamic" thing a static site ever needs. Everything else — pages, images, styles — is happily served as plain files from a CDN. So it feels absurd to bolt on a whole backend, adopt a heavier framework, or migrate to a CMS just so visitors can send you a message. The good news: you don't have to, and you never did.

A static site contact form works because the HTML <form> element can post to any URL on the web, not just a script on your own domain. onsubmit.dev provides that URL. Your form's action attribute points at your personal endpoint, the visitor's browser sends the message straight to us, and we validate it, filter out spam, store it, and email it to you — all within seconds.

That makes the implementation almost embarrassingly easy. There is no SDK, no build-step configuration, no environment variable, and no code beyond the form markup you would have written anyway. If your site is a hand-written HTML page, a Hugo blog, a Jekyll portfolio, or an Astro landing page, the setup is identical: paste one URL into one attribute and publish. Your site stays static, stays fast, and doesn't have to seek anything else.

How to add a contact form to a static site

Three steps, one attribute, live in minutes.

Step 01

Write the contact form in plain HTML

A static site contact form starts as ordinary markup: a name field, an email field, a message box, and a submit button. No library to install, no component to import, no snippet generator to configure — the <form> element you already know is the entire building block.

Copy the example below into any page of your site and adjust the fields to taste. It is valid on a hand-written HTML page and in every static site generator alike.

html
<form action="https://onsubmit.dev/f/your-form-id" method="POST">
  <input name="name" placeholder="Your name" required />
  <input name="email" type="email" placeholder="Email" required />
  <textarea name="message" placeholder="How can we help?" required></textarea>
  <button type="submit">Send message</button>
</form>
Step 02

Paste your endpoint into the action attribute

Create a free form on onsubmit.dev, copy the endpoint URL it gives you, and paste it into the form's action attribute. That one attribute is the whole integration. There is nothing to npm install, no serverless function to deploy, no API key to hide, and no backend to stand up.

The browser performs the POST natively, so the form works even for visitors with JavaScript disabled — and your site stays exactly as static as it was before.

02
Step 03

Read messages in your inbox

Every message a visitor sends is spam-filtered, stored in your dashboard, and emailed to you the moment it arrives. Want it elsewhere too? Forward each submission to Slack, Telegram, Discord, Google Sheets, Notion, Airtable, or any webhook — all configured with clicks, not code.

You publish HTML; we do the receiving, filtering, storing, and notifying. That division of labour is the whole idea.

03

Why this is the easiest contact form a static site can have

Everything a contact form touches is handled for you — your site just serves HTML.

Live in minutes, not days

One HTML attribute is the entire setup. Most people go from signup to a working static site contact form in under five minutes — no tutorial required.

Your site stays fully static

No serverless functions, no databases, no CMS migration. Your site remains plain files on a CDN — fast, cheap, and secure — and needs nothing else to accept messages.

Spam stopped before your inbox

Honeypot fields and keyword filters silently drop bot submissions, and blocked spam never counts against your quota — so a public contact form doesn't become a spam magnet.

Every message reaches you instantly

Email notifications arrive within seconds, and you can mirror messages to Slack, Telegram, or Discord so an enquiry never sits unread.

Your design, untouched

onsubmit.dev never injects widgets, iframes, or styles into your page. You keep full control of the markup and CSS — the form looks exactly how you built it.

Free to start, free to stay

The free tier covers 50 messages a month with no credit card — more than enough for a portfolio, personal site, or small business contact page.

Your static site should not need anything else

When developers first discover that static hosts like GitHub Pages, Cloudflare Pages, or Amazon S3 can't process a form, the common reflexes are to over-build: spin up a serverless function, embed a third-party widget, wire the form through mailto:, or abandon the static approach entirely for a CMS. Every one of those trades away the reason you went static in the first place — simplicity.

A serverless function is real code with real dependencies you now maintain, redeploy, and debug. Widgets load someone else's JavaScript and someone else's design onto your page. mailto: links depend on the visitor having a configured email client and expose your address to scrapers. And a CMS turns a folder of files into a stack of software with updates, plugins, and attack surface.

A hosted form endpoint sidesteps all of it. The contact form is the only piece that ever needed a server, so that is the only piece that lives on one — ours. Your site keeps its perfect Lighthouse scores, its free hosting, and its zero-maintenance deploys, and gains a fully working contact form without seeking anything else: no backend, no database, no cron jobs, no security patches.

Enhance it later, if you ever want to

Because the integration is a plain action attribute, the form works with JavaScript switched off — the most resilient setup there is. If you later want inline success messages instead of a redirect, progressively enhance the same form with a small fetch() call. The endpoint stays the same, the no-JS fallback stays intact, and your site stays static.

Works with every static site generator

The setup is identical everywhere — one attribute — and we have step-by-step guides for the tools you use.

Frequently asked questions

How do I add a contact form to a static site?

Write a normal HTML form, set its action attribute to your onsubmit.dev endpoint URL, and set the method to POST. That's the whole integration — the browser delivers each message to us, and we email it to you. No backend, plugin, or JavaScript is required.

Do I need a server or serverless function for a static site contact form?

No. The form posts directly from the visitor's browser to onsubmit.dev, so your site can stay 100% static. There is no function to write, no API route to deploy, and no infrastructure to maintain.

How hard is the setup, really?

It is one attribute. If you can edit an HTML file, you can add a working contact form in a few minutes: create a form in the dashboard, copy the endpoint URL, and paste it into your form's action attribute.

Will a public contact form on my static site attract spam?

Bots do target contact forms, which is why onsubmit.dev filters every submission through honeypot fields and keyword rules before it reaches you. Blocked spam is discarded silently and never counts toward your plan limit.

Does it work with Hugo, Jekyll, Astro, Eleventy, and plain HTML?

Yes. Because the integration is a standard form action, it works in any tool that outputs HTML — every static site generator, site builder, or hand-written page. We publish step-by-step guides for the most popular ones.

Can I style the contact form to match my site?

Completely. onsubmit.dev only receives the POST request — it adds nothing to your page. Your form is your own HTML and CSS, so it inherits your site's design automatically.

Put a contact form on your static site today

Free forever for up to 50 messages a month. One attribute, no backend, no credit card.