Adding a contact form to an Eleventy site
July 24, 2026
Eleventy people tend to be principled about shipping plain HTML — it's half the reason you chose 11ty. Good news: a contact form is the easiest place in your whole site to hold that line. No client JavaScript, no serverless function bolted to your static site, no build plugin.
1. Get an endpoint
Create a NormForms form — free tier,
no card. You'll get a URL like https://normforms.com/f/x7Kp2mQ9RtLw.
2. Add the form to a template or include
Works identically in Nunjucks, Liquid, WebC, or plain HTML files —
it's just markup. As an include (_includes/contact-form.njk):
<form action="https://normforms.com/f/YOUR_TOKEN" method="POST"> <input type="text" name="name" placeholder="Your name"> <input type="email" name="email" placeholder="Your email"> <textarea name="message" placeholder="Your message"></textarea> <input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off"> <button type="submit">Send</button> </form>
{% include "contact-form.njk" %}
Want more fields? Just add inputs — <input name="budget">,
a select, whatever. Any field name you send shows up in the notification
email with zero configuration. The _gotcha honeypot stays,
hidden and empty; it's doing more anti-spam work than it looks like.
3. Test from localhost
Submitting from npx eleventy --serve is automatic test mode —
the email arrives with a [Test] prefix and doesn't touch
your quota. Set your production domain in the form settings and
submissions from any other origin are silently dropped.
Scorecard
Client JavaScript added: 0 bytes. Build time impact: none. Spam filtering, delivery, storage, and a dashboard: included. Your 11ty site remains a folder of honest HTML files, now with a working front door.