使用 Resend 发送邮件
在 Cloudflare Workers 上配置 Better Auth 与联系邮件的 Resend 投递。
事务邮件通过 Resend 完整接入。邮箱验证、密码重置与联系消息共用
sendEmail() 和 React Email 模板。Newsletter 模板只是附带资源,没有接入用户
流程。
已包含的流程
| 流程 | 调用位置 | 模板 | 收件人 |
|---|---|---|---|
| 邮箱验证 | src/lib/auth.ts | verify-email.tsx | 新用户 |
| 密码重置 | src/lib/auth.ts | forgot-password.tsx | 发起重置的用户 |
| 联系表单 | src/routes/api/contact.ts | contact-message.tsx | websiteConfig.mail.supportEmail |
| Newsletter | 未接通 | subscribe-newsletter.tsx | 无 |
src/lib/email/index.ts 在首次调用 sendEmail() 时延迟创建 Resend client。这种
请求期初始化对 Workers 很重要:服务端 secret 不应在顶层模块求值时被捕获。
Resend SDK 通过其 HTTP API 投递,适合 Worker runtime。
email-layout.tsx 与 email-button.tsx 提供共用 React Email 外壳和按钮。当前
邮件主题与模板为英文;UI 国际化不会自动让邮件本地化。
subscribe-newsletter.tsx 只是可复用模板。项目没有订阅接口、订阅者表、确认
流程、偏好中心或退订流程。
配置
创建 Resend key
本地开发把服务端值加入 .env:
RESEND_API_KEY=re_your_key生产环境存为 Worker secret:
pnpm wrangler secret put RESEND_API_KEY不要改成 VITE_*,也不要提交进 wrangler.jsonc。
验证发送域名
添加 Resend 要求的 DNS 记录并等待验证;再按投递策略配置 SPF、DKIM 与 DMARC。
设置发件人与支持邮箱
修改 src/config/website-config.ts:
mail: {
provider: "resend",
fromEmail: "Example <noreply@mail.example.com>",
supportEmail: "support@example.com",
}fromEmail 必须被已验证的 Resend 域名允许;supportEmail 接收联系表单消息。
本地行为与错误
没有有效 key 时,sendEmail() 会捕获 provider 错误并返回
{ success: false, error },不会投递邮件。应用仍可用于本地 UI/数据库开发,但
验证和重置流程无法完成端到端测试。
当前认证 callback 会等待 sendEmail(),却不会检查其结构化结果;联系接口也
没有向客户端传播 provider 返回的失败,因此 Resend 拒绝邮件时,请求仍可能显示
成功。在关键流程依赖邮件前,应记录不含敏感数据的失败标识,并按产品策略选择
传播、重试或入队。
联系接口会用 Zod 校验姓名、邮箱、主题和消息长度,但它是公开接口。上线前增加 限流、垃圾/滥用防护与可观测性。
自定义模板
修改 src/lib/email/templates 下的文件,让共用布局适合全部事务邮件。品牌替换时
也要修改硬编码的 SoarStarter footer 与当前年份处理。
邮件本地化应由触发流程显式传入 locale,再选择对应主题和模板文案。延迟任务不应 从浏览器状态猜语言;需要可靠本地化时应保存用户所选语言。
验证
- 注册用户并收到验证邮件,链接使用生产 origin 且可完成验证。
- 发起密码重置并通过收到的链接完成流程。
- 提交联系表单,配置的支持邮箱收到消息。
- 非法联系 payload 校验失败,滥用流量被 spam 防护拒绝。
- API key 缺失/无效时服务端有可见诊断,且不泄露正文或 secret。
- 监控 Resend 控制台事件、退信与投诉。
生产注意事项
遵守 provider 的发件人和速率限制。关键邮件应增加重试/队列,在 callback 可能 重复时考虑幂等,并为持续投递失败告警。不要记录收件人或正文。认证 URL 应使用 部署 origin,Worker secret 通过 Wrangler 轮换。
