integrations · hosting platform

A contact form on Cloudflare Pages, without writing a Worker.

Cloudflare Pages will serve your site from 300-odd cities and never once accept a form submission for you. There is no equivalent of Netlify Forms here. Cloudflare's own tutorial on the subject sends you to a third-party form service, and the closest first-party thing, the Static Forms plugin for Pages Functions, is not a form service at all: it intercepts the POST and then hands it to a function you have to write, wired to a KV namespace you have to provision.

Pointing your form's action at a mailcontact endpoint removes that whole layer. No Functions directory, no KV binding, no wrangler config, no Worker to keep alive. Submissions land in your project's inbox and you get pinged in Discord, Slack, email, or a webhook.

the snippet

A working form for Cloudflare Pages, in one paste.

Point the form at your project's mailcontact endpoint. Submissions land in your project inbox. No server, no API route, no email service to wire up.

public/contact.html
<!-- No functions/ directory. No KV namespace. No wrangler.toml. -->

<form action="https://mailcontact.app/api/forms/your-form-id" method="POST">
  <input type="text" name="name" placeholder="Your name" required />
  <input type="email" name="email" placeholder="you@email.com" required />
  <textarea name="message" placeholder="What's on your mind?" required></textarea>

  <!-- Bots fill this in. Humans never see it. -->
  <input type="text" name="_gotcha" tabindex="-1" autocomplete="off" hidden />

  <button type="submit">Send</button>
</form>

how it works

Three steps, start to finish.

01

Create an inbox

One inbox per project. Name it after the Pages project and you get a form endpoint and a project email address straight away.

02

Paste the form into your output

Whatever you deploy to Pages, whether that is plain HTML, an Astro build, or a React bundle, the form is just markup in the page. Nothing changes in your build command.

03

Deploy as usual

git push, or wrangler pages deploy. The form works on the first preview deployment, on every branch alias, and on your custom domain, with no per-environment setup.

why mailcontact

Built to pair well with Cloudflare Pages.

The Static Forms plugin is not a form backend

It parses the submission and calls a handler you supply. You still write the persistence, the notification, the spam handling and the error paths. That is the actual work, and the plugin does none of it.

Nothing to keep inside the free tier

Workers bill on requests and CPU time, and a form handler that emails you drags in a mail API and its own key. An endpoint you post to has no invocation budget to blow and no cold path to debug at 2am.

It survives the Pages to Workers drift

Cloudflare now steers new full-stack projects toward Workers. A form that is markup pointing at an external URL does not care which product your site ends up living on, because it has no platform binding to migrate.

faq

Cloudflare Pages + mailcontact, answered

Does Cloudflare Pages have built-in form handling like Netlify Forms?

No. Netlify detects a form attribute at deploy time and stores submissions for you; Cloudflare has no such feature. Cloudflare's documented answers are either the Static Forms plugin, which requires you to write the handler and wire storage yourself, or an external form service. There is no zero-code option in the platform.

What about the Static Forms plugin for Pages Functions?

It is plumbing, not a product. The plugin catches the POST from a form marked with data-static-form-name and passes it to a respondWith handler that you implement. Persisting the message, notifying you, and filtering spam are all still yours to build. If you want to write that, the plugin helps; if you wanted to skip it, an endpoint is the shorter path.

Can I still use Pages Functions for other things?

Yes. Nothing here conflicts. The form is an HTML action attribute pointing at another origin, so your functions/ directory, middleware, and bindings are untouched. This only replaces the part of Functions you would have written to handle a contact form.

Will the form work on preview deployments and branch aliases?

Yes. The endpoint accepts cross-origin posts from any domain, so your *.pages.dev previews, branch aliases, and custom domain all post to the same inbox without per-environment configuration or an allowlist to maintain.

related

Also works with

One inbox for every Cloudflare Pages project you ship.

Forms and a real email address, together, with notifications where you live. Launching soon. Be the first to know.

No spam. It's kind of our thing.