Skip to content

SOPs

Custom Domain Email — Cloudflare Routing + Resend + Gmail Alias

Custom domain email without paying for Google Workspace or running a mail server. Three free pieces wired together:

  1. Cloudflare Email Routing — receives inbound mail on @mytechsupport.com and forwards it to ojhurst@gmail.com.
  2. Resend — transactional email API. Handles outbound sending with DKIM-signed delivery that the big inboxes actually accept.
  3. Gmail “Send mail as” alias — lets Gmail compose and reply as james@mytechsupport.com by routing outgoing messages through Resend’s SMTP relay.

End result: you write and read everything from your normal Gmail UI. Incoming mail lands in your regular inbox. Outgoing mail goes out as the custom address, DKIM-signed from your own domain. Zero monthly cost, zero servers.

Google Workspace is $7/month per user per domain. For a single alias on a side project, that is $84/year to move bytes. The Cloudflare + Resend + Gmail stack delivers the exact same user-visible behavior for free because:

  • Cloudflare Email Routing is free and handles unlimited inbound forwarding per zone.
  • Resend’s free tier is 3,000 emails per month, which covers everything short of a real transactional product.
  • Gmail already hosts your reading UI, and its “Send mail as” feature was designed precisely for this.

The one thing you give up is a dedicated IMAP mailbox for the custom address. All mail lives in the underlying Gmail account. For a side-domain address like james@mytechsupport.com that is a feature, not a bug.

Running your own Postfix + Dovecot on a VPS technically works, but deliverability is the killer. VPS IP ranges from Hostinger, DigitalOcean, and similar providers are pre-blocked by Gmail and Outlook. You would need perfect SPF, DKIM, DMARC, reverse DNS, and weeks of IP warm-up before big inboxes will even accept your mail. Fun project, painful daily driver. Don’t.

INBOUND OUTBOUND
------- --------
sender Gmail compose window
│ │
│ MX │ SMTP (TLS, port 587)
▼ ▼
route1/2/3.mx.cloudflare.net smtp.resend.com
│ │
│ Cloudflare Email Routing │ Resend
│ rule: james@mts → ojhurst │ DKIM-signs with cf2024-1._domainkey
▼ ▼
ojhurst@gmail.com inbox recipient inbox

Inbound and outbound are fully independent paths. One breaking does not affect the other.

This is the live setup for mytechsupport.com as of 2026-04-15. Use it as a template when adding the same pattern to another domain.

All in the Cloudflare mytechsupport.com zone.

TypeNameValuePurpose
MX@route1.mx.cloudflare.net (prio 57)Inbound — Cloudflare Email Routing
MX@route2.mx.cloudflare.net (prio 51)Inbound — Cloudflare Email Routing
MX@route3.mx.cloudflare.net (prio 63)Inbound — Cloudflare Email Routing
TXT@v=spf1 include:resend.com include:_spf.mx.cloudflare.net ~allSPF — authorizes Resend and Cloudflare
TXTcf2024-1._domainkeyv=DKIM1; h=sha256; k=rsa; p=MIIBIjAN...DKIM key for Resend
TXT_dmarcv=DMARC1; p=none; rua=mailto:reports@dmarc.jameshurst.com;DMARC reporting

Cloudflare’s Email Routing UI adds the MX records automatically when you enable it. Resend adds the SPF and DKIM records automatically when you verify the sending domain.

Set in Cloudflare Dashboard → Email → Email Routing → Routes:

MatchAction
james@mytechsupport.comForward to ojhurst@gmail.com
support@mytechsupport.comForward to ojhurst@gmail.com
Catch-all(optional — forward or drop)

Dashboard → Domains → Add Domain → mytechsupport.com. Resend generates DKIM + SPF records for you. Paste them into Cloudflare DNS and click verify.

Once verified, Resend will accept SMTP auth from any address at the domain — no per-address setup.

Gmail Settings → Accounts and Import → Send mail as → Add another email address:

FieldValue
NameJames Hurst
Email addressjames@mytechsupport.com
Treat as an aliasUNCHECKED
SMTP Serversmtp.resend.com
Port587
Usernameresend
PasswordResend API key (e.g., re_xxxxxxxx...)
Secured connectionTLS

Unchecking “Treat as an alias” is important. When checked, Gmail merges outgoing mail as if it came from the same person — replies get threaded under your Gmail identity. Unchecked, james@mytechsupport.com is treated as a separate sender identity, which is what you want when the address represents a different context or brand.

After clicking Add Account, Gmail sends a confirmation link to the custom address. Cloudflare Email Routing forwards that email to your real Gmail inbox. Click the confirmation link and the alias is live.

NameWhere storedUsed by
RESEND_MTSshared-secrets.envGmail SMTP auth, MTS Vercel env (RESEND_API_KEY)

The same Resend key is used for both the Gmail alias and the production MyTechSupport.com Next.js app’s transactional email (RESEND_API_KEY in Vercel). Rotating the key requires updating both places — see the rotation checklist below.

When a Resend key is leaked or needs to be rotated:

  1. Create a new key in the Resend dashboard with the same permissions (Sending access is enough for this use case).
  2. Update shared-secrets.env:
    Terminal window
    python3 ~/apps/cc/secrets/secrets_cli.py add RESEND_MTS 're_new_value'
  3. Update .env.local in the mytechsupport repo with the new value.
  4. Update all three Vercel environments (production, preview, development):
    Terminal window
    cd ~/apps/mytechsupport
    for ENV in production preview development; do
    vercel env rm RESEND_API_KEY $ENV --yes
    printf '%s' 're_new_value' | vercel env add RESEND_API_KEY $ENV
    done
  5. Bump build number and push — this triggers a Vercel redeploy so production picks up the new key from its env vars. Key changes alone do not redeploy.
  6. Update the Gmail alias password — Gmail Settings → Accounts → edit the Send mail as entry and paste the new key into the SMTP password field.
  7. Verify production email is working by triggering a test send (e.g., a password reset).
  8. Verify Gmail alias is working by sending a test message as james@mytechsupport.com.
  9. Revoke the old key in the Resend dashboard.

Do not revoke the old key until you have confirmed all three consumers (Vercel production, Gmail alias, shared-secrets) are on the new one. Otherwise you will get delivery failures that are hard to correlate.

SymptomCauseFix
Sent mail disappears, no bounceGmail alias using stale SMTP passwordUpdate the Send mail as SMTP password to the current Resend key
Bounce: 550 5.7.26 ... DKIM/SPFDKIM record missing or wrongRe-verify domain in Resend dashboard, confirm Cloudflare DNS matches
Bounce: 421 unable to verify senderSPF record missing include:resend.comAdd resend.com to the SPF record at the zone apex
Inbound mail not forwardingCloudflare routing rule missing or address not addedCheck Cloudflare → Email → Email Routing → Routes
Gmail verification email never arrivesCloudflare routing rule for the custom address is missingAdd the forwarding rule before clicking “Add Account” in Gmail
Gmail shows “could not authenticate”Wrong usernameUsername is literally the string resend, not the email address

To add the same pattern for a new domain (e.g., hello@newdomain.com):

  1. Add the domain to Cloudflare and let it manage DNS.
  2. Enable Email Routing on the zone — Cloudflare adds the MX records.
  3. Add a routing rule for the custom address pointing to your real Gmail.
  4. Add the domain to Resend — paste Resend’s SPF and DKIM records into Cloudflare DNS.
  5. Add a “Send mail as” alias in Gmail using smtp.resend.com and a Resend API key (reuse the existing key or create a new one for audit isolation).
  6. Save the key to shared-secrets with a domain-specific name if you made a new one (e.g., RESEND_NEWDOMAIN).

The same Resend account can send from any number of verified domains on its free tier. No per-domain charges.