这篇文章按这个仓库的实际结构,整理一套可以直接照着做的上线流程:官网、首页联系表单,以及企业邮箱收件转发。

这个项目不是传统多页面站点,也没有单独的 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,先做完这三步:

  1. 在 Cloudflare 后台添加域名。
  2. 去域名注册商后台,把 nameservers 改成 Cloudflare 分配给你的那组。
  3. 等域名状态变成 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_TOMAIL_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 后台加一个发信域名。通常会单独用一个子域名发信,比如:

这么做主要是把网站域名和发信信誉分开,后面排查问题会省事很多。

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.html
  • assets/

不建议直接把整个仓库根目录丢给 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 后台按这个顺序走:

  1. 打开 Workers & Pages。
  2. 进入你的 Pages 项目。
  3. 找到 Custom domains。
  4. 添加 example.com
  5. 再添加 www.example.com

如果你绑定的是根域名 example.com,这个域名必须已经是当前账号下的 Cloudflare zone,nameservers 也要先切到 Cloudflare。

Cloudflare Email Routing 负责企业邮箱收件转发

这里说的企业邮箱,更准确一点,是企业域名邮箱的收件转发。它不是完整的办公邮箱系统,但对官网早期已经够用:

对官网初期来说,这种方式足够轻,也省维护成本。你不用自己管邮件服务器,也不用一开始就上完整企业邮箱套件。

开启 Email Routing

前提还是一样:域名已经托管到 Cloudflare。

在 Cloudflare 后台操作:

  1. 进入你的域名。
  2. 打开 Email Routing。
  3. 选择 Add records and enable。

Cloudflare 会自动加上 Email Routing 需要的 MX 和 TXT 记录。

这里常见的问题是,如果当前域名已经有别的收件 MX 记录,Cloudflare 会提示你处理。想用 Cloudflare Email Routing,就不能同时保留另一套负责收信的 MX,不然很容易卡住。

创建对外邮箱并转发到个人邮箱

继续在 Email Routing 里建规则:

  1. 进入 Routing rules。
  2. 选择 Create address。
  3. 建一个地址,比如 [email protected]
  4. Destination address 填你的个人邮箱,比如 [email protected]
  5. 去个人邮箱点开验证邮件。
  6. 完成验证。

验证通过后,别人发到 [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 负责收。

推荐你按这个顺序上线

按下面这个顺序做,基本不会绕路:

  1. 先把域名接到 Cloudflare,完成 nameservers 切换。
  2. 在 Resend 验证发信域名。
  3. wrangler.toml 里的域名、白名单、收件邮箱和发件邮箱改成自己的。
  4. 配置 RESEND_API_KEY
  5. 部署 Worker,先确认 /api/inquiry-email 能返回正常结果。
  6. 整理 release/ 目录。
  7. 把静态页发布到 Cloudflare Pages。
  8. 给 Pages 绑定正式域名。
  9. 打开官网,手动提交一条测试表单。
  10. 开启 Cloudflare Email Routing。
  11. 创建 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 上。