这篇文章按这个仓库的实际结构,整理一套可以直接照着做的上线流程:官网、首页联系表单,以及企业邮箱收件转发。
这个项目不是传统多页面站点,也没有单独的 contact.html。联系功能就在首页底部的 #contact 区块里,所以上线后的形态就是一个单页官网,底部带联系表单。如果目标是先把官网和联系入口一起放上去,这种结构反而更省事。
项目结构和请求链路
仓库里真正跟上线有关的文件就这些:
index.html:首页主体,联系表单也在这里。assets/styles/main.css:页面样式。assets/scripts/main.js:前端交互、语言切换、表单提交。assets/runtime-config.json:前端表单提交地址,默认是/api/inquiry-email。workers/inquiry-email.js:Cloudflare Worker,接收表单数据后调用 Resend 发邮件。wrangler.toml:Worker 的名字、域名路由和环境变量。
请求链路如下:
用户打开官网
-> 填写首页底部的联系表单
-> 浏览器请求 /api/inquiry-email
-> Cloudflare Worker 收到数据
-> Worker 调用 Resend 发邮件
-> 你的邮箱收到询盘通知
企业邮箱收件是另一条线:客户直接发邮件到 hello@你的域名 或 sales@你的域名,这部分不走 Resend,而是交给 Cloudflare Email Routing 转发到你的个人邮箱。
上线前要准备什么
- 一个 Cloudflare 账号。
- 一个 Resend 账号。
- 一个你自己的域名,比如
example.com。 - 本地可以执行
npx wrangler。
如果你打算直接用根域名做官网,比如 https://example.com,那域名最好已经完整托管到 Cloudflare。后面要用自定义域名、Worker 路由和 Email Routing,这一步绕不过去。
如果域名还没接到 Cloudflare,先做完这三步:
- 在 Cloudflare 后台添加域名。
- 去域名注册商后台,把 nameservers 改成 Cloudflare 分配给你的那组。
- 等域名状态变成 Active。
这一步看起来基础,但后面的自定义域名、Worker 路由和 Email Routing 都依赖它。
把项目改成你自己的配置
这个仓库默认写的是 ennota.cn。正式部署前,需要先把域名、收件地址、发件地址和页面文案换成你自己的,不然表单和路由都会指错地方。
改 wrangler.toml
这份配置决定了 Worker 挂到哪个域名、允许谁来调用表单接口,以及邮件发给谁。
name = "your-inquiry-worker"
main = "workers/inquiry-email.js"
compatibility_date = "2026-06-07"
routes = [
{ pattern = "example.com/api/*", zone_name = "example.com" },
{ pattern = "www.example.com/api/*", zone_name = "example.com" },
]
[vars]
ALLOWED_ORIGIN = "https://www.example.com,https://example.com"
RESEND_API_BASE = "https://api.resend.com"
MAIL_TO = "[email protected]"
MAIL_CC = ""
MAIL_FROM = "[email protected]"
MAIL_FROM_NAME = "Your Website"
MAIL_SUBJECT_PREFIX = "[Website Inquiry]"
这里最容易写错的是下面几项:
routes:把你域名下的/api/*交给 Worker。ALLOWED_ORIGIN:允许哪些站点来源调用这个接口。正式域名如果有www和不带www两种写法,都写进去。MAIL_TO:询盘最后发到谁。MAIL_FROM:Resend 实际拿来发信的地址,必须属于你在 Resend 已验证的域名。
MAIL_TO 和 MAIL_CC 都支持逗号分隔多个地址。
再看一下 assets/runtime-config.json
当前仓库默认是同域名方案,所以前端会直接请求:
{
"formEndpoint": "/api/inquiry-email"
}
这种写法的前提是:
- 官网跑在
https://example.com - Worker 也挂在
https://example.com/api/*
如果你就是按这套方式部署,不用改。
只有在官网和 Worker 分开部署时,才把这里改成完整地址,比如:
{
"formEndpoint": "https://your-worker.workers.dev/api/inquiry-email"
}
页面文案和 Logo 在哪里改
index.html:公司名、电话、地址、页脚。assets/i18n/*.json:多语言文案。assets/logo/:Logo 和 favicon。
如果你只是要先把站上线,最少也要把公司名称、联系电话和邮箱相关信息换掉,不然看起来就像测试站。
联系表单发信用的是 Resend
这个仓库里的联系表单不是直接从前端发邮件。前端只负责提交 JSON,真正发信的是 workers/inquiry-email.js,它会调用 Resend 的 API。
先在 Resend 后台加一个发信域名。通常会单独用一个子域名发信,比如:
- 官网:
example.com - 发信域名:
mail.example.com或notify.example.com - 发件地址:
[email protected]或[email protected]
这么做主要是把网站域名和发信信誉分开,后面排查问题会省事很多。
Resend 会要求你加几条 DNS 记录。因为域名已经托管在 Cloudflare,所以把它给出的记录直接加到 Cloudflare DNS 里就行。域名状态变成 verified 之后,再继续下面这一步。
把 Resend API Key 写进 Worker secret:
npx wrangler secret put RESEND_API_KEY
这个 key 不要写进仓库。放 secret 里就够了。
表单 Worker 先单独部署
可以先把 Worker 单独部署起来,先确认表单接口是通的。接口通了,再发静态页会更稳。
在项目根目录执行:
npx wrangler deploy
如果 wrangler.toml 里的路由已经改成你自己的域名,部署后可以直接测这个地址:
curl https://example.com/api/inquiry-email
正常会返回:
{ "ok": true, "service": "inquiry-email" }
如果这里不通,先检查这几项:
routes写的域名是不是你现在真正在用的那个。- 域名是不是已经托管在当前 Cloudflare 账号下。
- Worker 是不是部署到了正确账号。
ALLOWED_ORIGIN有没有把正式域名写全。
官网静态页最好单独打一个发布目录
这个仓库里真正要公开出去的静态资源只有两部分:
index.htmlassets/
不建议直接把整个仓库根目录丢给 Pages。根目录里还有 workers/ 和 wrangler.toml,这些文件不需要对外公开。
最稳妥的做法是先整理一个 release/ 目录:
mkdir -p release
cp index.html release/
cp -R assets release/
然后把这个目录发布到 Cloudflare Pages:
npx wrangler pages deploy release --project-name your-landing-site
部署完成后,Cloudflare 会先给你一个 *.pages.dev 地址。可以先用它检查页面和静态资源,再绑定正式域名。
正式域名怎么挂到 Pages
到 Cloudflare 后台按这个顺序走:
- 打开 Workers & Pages。
- 进入你的 Pages 项目。
- 找到 Custom domains。
- 添加
example.com。 - 再添加
www.example.com。
如果你绑定的是根域名 example.com,这个域名必须已经是当前账号下的 Cloudflare zone,nameservers 也要先切到 Cloudflare。
Cloudflare Email Routing 负责企业邮箱收件转发
这里说的企业邮箱,更准确一点,是企业域名邮箱的收件转发。它不是完整的办公邮箱系统,但对官网早期已经够用:
- 对外告诉客户:你可以发到
[email protected] - 实际上:Cloudflare 把邮件转发到你的个人邮箱,比如
[email protected]
对官网初期来说,这种方式足够轻,也省维护成本。你不用自己管邮件服务器,也不用一开始就上完整企业邮箱套件。
开启 Email Routing
前提还是一样:域名已经托管到 Cloudflare。
在 Cloudflare 后台操作:
- 进入你的域名。
- 打开 Email Routing。
- 选择 Add records and enable。
Cloudflare 会自动加上 Email Routing 需要的 MX 和 TXT 记录。
这里常见的问题是,如果当前域名已经有别的收件 MX 记录,Cloudflare 会提示你处理。想用 Cloudflare Email Routing,就不能同时保留另一套负责收信的 MX,不然很容易卡住。
创建对外邮箱并转发到个人邮箱
继续在 Email Routing 里建规则:
- 进入 Routing rules。
- 选择 Create address。
- 建一个地址,比如
[email protected]。 - Destination address 填你的个人邮箱,比如
[email protected]。 - 去个人邮箱点开验证邮件。
- 完成验证。
验证通过后,别人发到 [email protected] 的邮件,就会自动转发到你的个人邮箱。
如果你刚开始搭站,通常这几个地址就够用了:
团队还小的时候,这几个都先转发到同一个邮箱也没问题。
还有一个限制最好提前知道:Cloudflare Email Routing 默认一个自定义地址只转发到一个目标邮箱。如果你想把 [email protected] 同时转给好几个人,默认规则做不到,需要再加 Worker 处理,而且每个目标邮箱都要先验证。
发信和收信是两套东西
第一次配这套东西时,很容易把 Resend 和 Email Routing 当成一回事。实际上它们分工很清楚。
联系表单通知邮件是 Resend 在发:
- 首页表单提交给 Worker。
- Worker 调 Resend。
- Resend 把询盘通知发到你的收件箱。
企业邮箱收件转发是 Cloudflare Email Routing 在做:
- 客户直接发到
[email protected]。 - Cloudflare 收到邮件。
- Cloudflare 转发到你的个人邮箱。
简单理解就是:Resend 负责发,Email Routing 负责收。
推荐你按这个顺序上线
按下面这个顺序做,基本不会绕路:
- 先把域名接到 Cloudflare,完成 nameservers 切换。
- 在 Resend 验证发信域名。
- 把
wrangler.toml里的域名、白名单、收件邮箱和发件邮箱改成自己的。 - 配置
RESEND_API_KEY。 - 部署 Worker,先确认
/api/inquiry-email能返回正常结果。 - 整理
release/目录。 - 把静态页发布到 Cloudflare Pages。
- 给 Pages 绑定正式域名。
- 打开官网,手动提交一条测试表单。
- 开启 Cloudflare Email Routing。
- 创建
hello@、sales@这类地址并转发到个人邮箱。
这个顺序的好处是,先把接口打通,再发页面,最后补企业邮箱收件,排查起来比较清楚。
几个最常见的问题
页面能打开,但表单发不出去,先查这几项:ALLOWED_ORIGIN 有没有把正式域名写全,RESEND_API_KEY 有没有配置,前端的 formEndpoint 有没有指到正确地址。
Worker 已经部署了,但邮箱始终收不到,先看 MAIL_FROM 是不是来自 Resend 已验证域名,再看 MAIL_TO 填得对不对。很多时候不是代码问题,就是发件域名没验证完。
官网可以访问,但 /api/inquiry-email 返回 403,通常是来源白名单不匹配。尤其是 www 和不带 www 混用的时候,很容易漏一个。
Email Routing 开不了,通常就三种情况:域名还没完全接管到 Cloudflare,nameservers 还没生效,或者 DNS 里还留着别家的收件 MX。
页面部署没问题,但表单请求跑错地址,回头看 assets/runtime-config.json。同域名部署就保留 /api/inquiry-email,分开部署才改成完整 URL。
本地预览页面,用这条命令就够了
如果你只是想先看首页效果,在项目根目录跑:
python3 -m http.server 4173
然后打开:
http://127.0.0.1:4173
这适合先看页面和文案。要本地联调表单,还得额外把 Worker 跑起来,再把 formEndpoint 指到本地或测试接口。
附一份最短命令清单
# 配置 Resend API Key
npx wrangler secret put RESEND_API_KEY
# 部署表单 Worker
npx wrangler deploy
# 整理静态站发布目录
mkdir -p release
cp index.html release/
cp -R assets release/
# 发布官网到 Cloudflare Pages
npx wrangler pages deploy release --project-name your-landing-site
剩下的动作都在 Cloudflare 后台完成:
- 给 Pages 绑定正式域名。
- 在 Email Routing 里建收件转发规则。
这个仓库本身已经把官网和联系表单的主链路搭好了。剩下的工作主要是把域名、DNS 和邮箱配置换成自己的,然后按顺序挂到 Cloudflare 和 Resend 上。