Part II: Pick a Path (and build the thing)08
Chapter 08Add-on
Forms and email (all Cloudflare, no extra accounts)
Save first, then email. Always.
The classic setup is a contact form from one company, a spam filter from another, an email sender from a third, and a monthly fee for each. Then the form breaks and nobody knows which of the three to blame.
Cloudflare does all of it, and most of it is free:
| Job | Cloudflare piece | In plain terms | Plan |
|---|---|---|---|
| Stop spam | Turnstile | A "prove you're human" check that's usually invisible. No clicking traffic lights. | Free |
| Save every submission | D1 | A small database, so a message is never lost even if an email fails | Free |
| Email you when someone submits | Email Routing send | Sends to your own verified inbox | Free |
| Receive email at your domain | Email Routing | hello@yourbakery.ca forwarded to your existing Gmail | Free |
| Email the visitor (a confirmation) | Email Service | Sends to anyone, from your domain | $5/month plan |
So the one question is: does your site need to email anyone other than you?
- No (most sites): a contact form that lands in your inbox and a
hello@address you read in Gmail. $0. - Yes: "thanks, we got your message" confirmations, booking confirmations, order emails. That's the $5 Workers Paid plan, with 3,000 emails a month included.
Honestly, most small businesses don't need the confirmation email. You're going to reply personally anyway, and that reply is the confirmation.
The forms prompt
Add a contact form to my site, and set up email on my domain. Do all of it
through the Cloudflare API and wrangler, using my keys.
Form:
- Fields: [name, email, phone, message, plus anything specific: event date,
budget, service type...]. Design it to match the site, including clear
error and success states.
- Protect it with Turnstile. Create the widget through the API, put the site
key in the site config and the secret in a Worker secret (save it to my
vault too as TURNSTILE_SECRET_KEY). Add rate limiting as well.
- Save every submission to a D1 database first, THEN send the email. If the
email fails, the submission must still be saved. Apply the database
migrations in the deploy workflow.
My Cloudflare Workers plan is [Free / Paid]. On Free, only send to my own
verified address and skip the visitor confirmation. On Paid, do both.
Sending:
- Set up sending from my domain. Add every DNS record
it needs (SPF, DKIM, DMARC, anything else) and verify the domain. If SPF or
DMARC records already exist, merge into them. Never create a second one,
and never replace or remove MX records.
- Send each submission to [YOUR EMAIL], from a no-reply address on my
domain, with reply-to set to the person who filled in the form so I can
just hit reply.
- [Paid plan only] Send the visitor a short, friendly confirmation email that sounds like the
rest of the site. It must not repeat anything they typed (otherwise
spammers use your form to send their message to strangers), and rate
limit it per recipient address.
Receiving:
- Set up Email Routing so [hello@MYDOMAIN] forwards to [YOUR EMAIL]. Tell me
when to click the verification email Cloudflare sends me. If MX records or
a rule for this address already exist, leave them alone, even if an API
status check says routing isn't configured.
Then test it end to end on staging: submit the form in a visible browser
window (Turnstile won't pass a hidden, automated one, so use Turnstile's test
keys if you automate it), confirm the submission is in D1, and confirm the
email was sent. Tell me to check my inbox (and spam
folder).Can I reply as hello@mydomain from Gmail?
Yes, for free. Email Routing handles the receiving side. For sending, Gmail has a "Send mail as" feature that lets you pick hello@yourbakery.ca in the From box.
The catch on the free route: your email goes out through Gmail's servers, but it's not signed as your domain. Most inboxes accept it fine. A few strict ones put it in spam, and your domain's email security has to be set loose enough to allow it. For a bakery replying to customers, that's usually fine. For a business where every email matters, pay the $5 and send through Cloudflare instead, which signs it properly.
Here's what you do, because it's your Google account:
- Turn on 2-Step Verification for your Google account if it isn't on already.
- Go to myaccount.google.com/apppasswords, make an app password called "hello@ send-as", and copy it.
- Gmail → Settings → See all settings → Accounts and Import → Send mail as → Add another email address. Enter
hello@yourdomainand leave "Treat as an alias" ticked. - SMTP server
smtp.gmail.com, port587, username your full Gmail address, password the app password. TLS. - Gmail emails a confirmation code to
hello@yourdomain, which Email Routing forwards straight back to you. Click it.
Personal details are blurred. Press play, it's silent and loops.
Then have the agent fix the DNS side:
I send email as [hello@MYDOMAIN] from Gmail using smtp.gmail.com (Send mail
as). Update my domain's SPF record to include Google (merge with what's
there, never a second SPF record), and make sure my DMARC policy won't
reject these emails (relaxed alignment, p=none or quarantine). Don't touch
the MX records. Then tell me how to check it works: send a test to a
mail-tester style address and read me the score.On the $5 plan instead? Tell the agent: "Set up Cloudflare Email Service SMTP so I can use Gmail's Send mail as for hello@mydomain, signed by my domain. Create the SMTP credentials, save the password to my vault, and give me the settings to paste into Gmail." You copy the password from Bitwarden into Gmail's Send mail as screen yourself (steps 3 to 5, with Cloudflare's server instead of smtp.gmail.com). The emails come out properly signed, so strict inboxes trust them.
Personal details are blurred. Press play, it's silent and loops.
Why "save first, then email"
Not in the plan
Want a newsletter? That's a different tool (and a different guide). Cloudflare Email Service is for messages your site sends, like form alerts and order confirmations, not marketing blasts.
On a phone, swipe left and right to turn pages.