Static sites need contact forms. Netlify offers Netlify Forms. Cloudflare offers email sending and turnstile spam protection, but nothing out of the box for forms end-to-end. I wrote a small package that combines these Cloudflare features. The contact form on this site uses it.
How it works
- Each form is a few lines of config: a title, an email subject, and which fields are allowed and required.
- The Worker only accepts submissions from the site’s own origin, checks the Turnstile
token, and emails the submission through Cloudflare’s Send Email binding, with Reply-To set to the sender.
- A Turnstile token has to be issued for the site’s hostname with the form’s name as its action, so a token from one form can’t be used to submit another.
- A rejected submission returns an error that names the field to fix, rather than a generic failure.
The Vue side
useFormsaves a draft to localStorage as you type, validates fields, shows a sending state, and resets the Turnstile widget after every attempt, because tokens are single-use.useTurnstileWidgetloads the Turnstile script once per page, however many forms there are.
Built with
TypeScript, Cloudflare Workers, Cloudflare Turnstile and Vue 3, with tests, published to GitHub Packages.