Static-site contact form checklist: shipping right in 2026
A practical, opinionated checklist for shipping a static-site contact form in 2026 - what to set up, what to skip, what to test before launch.
A static site - Hugo, Eleventy, Astro, plain HTML, or anything else that ships as files from a CDN - has no runtime. That makes a contact form the one piece of the site that has to reach off-platform to do its job. The good news is the decisions are well-trodden in 2026. The bad news is that "well-trodden" is not the same as "trivial" - there are still fifteen small choices that decide whether the form quietly drops leads two months after launch.
This is the launch checklist we use ourselves and recommend to teams shipping a static-site contact form. It is opinionated, it skips the conceptual tour (see the JAMstack contact form guide for that), and it is sorted by the order you actually do the work in.
Before you start
1. Decide what the form is for, in one sentence
Write the sentence down. "We want sales-qualified inbound leads with a budget signal." "We want bug reports with reproduction steps." "We want recruiter inbounds tagged by seniority." The sentence dictates every other choice - fields, retention, routing, follow-up. A form designed for "general contact" ends up doing none of the three above well.
2. List every field the form will collect
Then cross out the ones you cannot justify. A field nobody reads is a field that creates GDPR exposure and lowers completion. The rule of thumb: every field has to either change how you respond, or be required by law. Anything that just feels informative is dead weight.
3. Pick the destination for submissions before writing any HTML
Inbox? Slack channel? Notion database? CRM record? Decide first, then pick a form backend that hits that destination natively. Retro-fitting a Slack integration onto a backend that does not support it is how teams end up with three brittle middlewares between a form and a chat message.
Endpoint and delivery
4. Point the form action at a single hosted endpoint
A static site cannot accept a POST. The pragmatic choice in 2026 is a hosted form backend - one URL in the <form action> attribute and you are done.
<form action="https://formspring.io/f/abc123" method="POST">
<input type="email" name="email" required>
<textarea name="message" required></textarea>
<button>Send</button>
</form>
No JavaScript, no API keys in the front-end, no serverless function to maintain. If the brief is more exotic than a contact form, revisit step 1 before adding infrastructure.
5. Set a thank-you URL that lives on your own domain
The form backend's default success page is generic. A redirect to /thanks on your own domain is one configuration field and it pays for itself in analytics: you can fire a conversion event on the thank-you page, attribute it to a campaign, and reuse the same template for other forms.
6. Enable signed webhooks if anything downstream consumes the data
If submissions feed a CRM, an internal API, or a chat channel, the receiver needs proof the payload is real. HMAC-signed webhooks (industry-standard t=, v1=, raw-body hash) are the standard. Configure the secret, store it in your receiver's env, and verify on every request. Without verification, the webhook endpoint is a public POST that anyone can spoof.
7. Add an email notification with a meaningful subject line
The default "New submission" subject buries the lead in your inbox after a week of volume. Template the subject with at least the form name and one identifying field (New demo request from {{ email }}). Two-second change, week-of-launch quality-of-life win.
Spam protection
8. Add a honeypot field on day one
An invisible field that bots fill and humans do not. Zero user friction, zero third-party calls, and in our experience it catches the majority of low-effort automated spam before any other layer runs. There is no reason to ship without one.
<div style="position:absolute;left:-9999px" aria-hidden="true">
<input type="text" name="website" tabindex="-1">
</div>
Server side, if website is non-empty, drop the submission silently. Loud rejection just teaches the bot to try again.
9. Add hCaptcha or Turnstile only after you see real spam
A captcha is friction. Adding one before the form has actually been targeted is premature optimisation that hurts conversion. Watch the spam-pass-through rate for two weeks, then enable a privacy-friendly captcha (hCaptcha or Cloudflare Turnstile) if anything is leaking past the honeypot. Skip reCAPTCHA - its EU compliance posture is increasingly fragile and the accuracy gain over hCaptcha is marginal.
10. Layer content filtering for anything user-facing
If submissions feed a public-facing surface (testimonials, support board, community wall), add Akismet or AI moderation in front of publication. LLM-generated lead-gen spam in 2025 was clean enough on grammar to bypass content scoring, so AI moderation catches the patterns Akismet misses. For private inboxes, this layer is optional - the cost of a single bad submission is low.
Compliance and retention
11. Set per-form retention before you take the first real submission
GDPR's storage-limitation principle - Article 5(1)(e) of Regulation (EU) 2016/679 - says "only as long as needed". For a contact form, that is usually 30 to 90 days after the conversation ends. Configure auto-delete in the form backend so you do not accidentally accumulate a five-year archive of every inbound. Retention is a per-form decision - an applicant form might retain twelve months, a contact form thirty days.
12. Confirm the form backend's data residency matches your audience
If your audience is in the EU, EU-only storage avoids standard contractual clauses, transfer impact assessments, and the ongoing audit of US surveillance law. US-hosted backends are possible with SCCs but the paperwork is recurring. The marketing benefit of credibly saying "EU data residency" on the privacy page is independent of the legal one.
13. Sign the DPA before launch, not after
Every form backend that handles personal data on your behalf is a processor under GDPR, and you need a Data Processing Agreement with each. Some US services gate the DPA behind enterprise plans - check before you commit. Get it signed in the same week you ship the form; auditors and procurement teams ask for it later and "we will sort it next quarter" is not an answer.
14. Put a privacy notice next to the submit button
One sentence: "By submitting, you agree to our Privacy Policy." Link to the actual policy. For newsletter or marketing forms, add a separate, unchecked opt-in checkbox - pre-checked boxes do not satisfy GDPR consent.
Launch and monitor
15. Submit the form yourself from a clean browser
Open an incognito window, fill the form, hit submit. Confirm the email lands, the webhook fires, the dashboard shows the submission, the thank-you page renders, and the redirect is correct (the underlying redirect/status semantics live in RFC 9110 if you ever need to debug a misbehaving 302/303). Do this once before any visitor sees the form - across the forms we run, the most common launch-day bug is "the webhook endpoint env var was not deployed to production yet" and a clean-browser test catches it in thirty seconds.
16. Set up a delivery-failure alert
Webhooks fail - receivers go down, DNS blips, deploy windows. A good form backend retries with exponential backoff and shows you the delivery log; configure an email or Slack alert for permanent failure so you find out before the lead is two weeks stale. In our experience this single alert prevents the most common silent-loss pattern.
17. Watch the conversion funnel for the first two weeks
The submission count is the lagging metric. The leading metrics are: form views, form starts (any field focused), and form completions. If views are high but starts are low, the form is buried or the label is wrong. If starts are high but completions are low, a field is too intrusive. Two weeks of data tells you which.
18. Schedule a quarterly review
Add a calendar entry to revisit the form in 90 days. Check the retention rule still matches the conversation length, confirm spam filters are still tuned, prune fields nobody reads. Forms drift like any other surface - the difference is nobody owns them by default, so they drift further before being noticed.
The short version
If you want one sentence: point the form at a hosted backend with signed webhooks and EU storage, ship with a honeypot, set 90-day retention, and submit it yourself before announcing it. Everything else on this list is variations on those four moves.
Related from this desk
- JAMstack contact form: the complete 2026 guide - the conceptual tour that sits underneath this checklist.
- Honeypot vs reCAPTCHA vs hCaptcha: spam protection compared - the deeper read on the spam layer in the checklist.
- File uploads from HTML forms without S3 keys - the upload pattern for forms that need attachments, without leaking storage credentials.
- GDPR-compliant form submissions: what you need to know - the privacy posture that informs retention and consent decisions in the playbook.
- Product side: form backend.
If you want to ship it on Formspring, the free tier covers 50 submissions a month with no credit card. The checklist above maps one-to-one onto the dashboard.
Written by Florian Wartner
Florian Wartner
Founder of Formspring and Pixel & Process. Senior full-stack engineer based in Lübeck, Germany. Building developer-first SaaS with EU data residency and honest pricing.
Elsewhere