Contact form and newsletter signup
Contact / lead form + newsletter signup (+ handler)
For when the answer to “People submit something — a form, a signup, a message” is yes.
Validated fields, honeypot, spinner, real success/fail states — plus the server endpoint that validates again, because the browser half is UX, not a boundary.
Skip the rebuild
You do not write this one. It arrives in your project as ordinary source you can read, change and keep, with its audit record and its caveats beside it.
- Download the Playground. It is free and runs on your own machine.
- Start a new app and tick “People submit something — a form, a signup, a message”.
- This block is written in, along with anything else you ticked.
The mistake it removes
Two audit entries (contact 10/20, newsletter 13/20) are the same primitive; shipping one block means one thing to fix instead of two that drift.
What the audit found
Named rather than summarized. The reasoning behind each one ships inside the block, so it travels with the code instead of living on a page you have to trust.
- Rate limiter is in-memory, so serverless coverage is per-instance minor · API cost & abuse safety
- Delivery is the caller's job, so the privacy story is too minor · Privacy & data
What you still have to do
A copied file cannot own your secrets, your host or your legal obligations. This is the part the block deliberately does not claim.
- Serve the endpoint over HTTPS, and keep your own abuse rules for the traffic that gets past a honeypot. The browser half is UX and the server half validates again, which is the boundary; a determined submitter is still your problem.
- A keyboard-and-screen-reader pass on YOUR page. The block ships the wiring it can ship — aria-describedby linking each field to its error, aria-invalid flipped as the field is validated, an aria-live error summary, autocomplete tokens and an aria-hidden honeypot kept out of the tab order — but color contrast, heading order and the focus order across everything around it are properties of the page you drop this into, and no test here can see them. Run one manual keyboard pass and one screen-reader pass before you launch.
- A rate limiter backed by Redis or by your edge if the form is a spam target. The limiter shipped here is in-memory and on serverless covers a warm instance only.
What lands in your project
vanilla
- vanilla/form-kit.js
createForm({mount, endpoint, fields}) — or variant:'signup' for the email-only preset.
node
- node/submit-handler.js
createSubmitHandler({fields, onSubmit}). You provide delivery (email/CRM); it provides the guarantees.
Licensed MIT. It is a starting point, not a finished product.
Get it
Download the Playground See the other blocks
Nothing here is locked. The files are yours, in your folder, under a permissive license.
Questions
- Is Contact form and newsletter signup audited?
- Yes. A full due-diligence audit was run on 2026-07-17 and the verdict was a pass.
- What do I still have to do myself?
- Serve the endpoint over HTTPS, and keep your own abuse rules for the traffic that gets past a honeypot. The browser half is UX and the server half validates again, which is the boundary; a determined submitter is still your problem.
- How do I get this code?
- Download the Playground, start a new app, and tick “People submit something — a form, a signup, a message”. The block is written into your project as ordinary source you can read and edit.
All pre-built code blocks · Learn to build from zero · The coding guide