电子邮件
使用拆分包架构配置事务性邮件提供商
LaunchSaaS 通过拆分包设计提供邮件支持。核心包 @launchsaas/email 定义接口;每个提供商是独立的包,按需安装。
更新时间:2026-03-15
架构
@launchsaas/email ← 接口 + Email 类(始终需要)
@launchsaas/email-resend ← Resend(推荐,支持 Serverless)
@launchsaas/email-nodemailer ← Nodemailer(SMTP,仅 Node.js)你只需添加实际使用的提供商包,避免引入不需要的 SDK。
LaunchSaaS 默认使用
@launchsaas/email-resend。在你自己的应用中,可以安装任意偏好的提供商 —
Resend、Nodemailer 或自定义包。
设置邮件功能
1. 安装提供商包
在你的应用目录中选择一个提供商:
# Resend(推荐 — 支持 Serverless 和 Edge)
pnpm add @launchsaas/email-resend
# Nodemailer / SMTP(仅限 Node.js 运行时)
pnpm add @launchsaas/email-nodemailer2. 添加环境变量
将提供商的 keys 导出添加到应用的 env.ts,以便在启动时验证环境变量:
// src/env.ts
import { keys as emailKeys } from "@launchsaas/email-resend/keys";
export const env = createEnv({
extends: [
// ... 其他 keys
emailKeys,
],
// ...
});然后在 .env 中设置变量:
# Resend
RESEND_API_KEY="re_..."
RESEND_FROM_EMAIL="[email protected]"
# — 或者 — Nodemailer (SMTP)
SMTP_HOST="smtp.example.com"
SMTP_PORT="587"
SMTP_USER="[email protected]"
SMTP_PASS="your-password"
SMTP_FROM_EMAIL="[email protected]"
SMTP_SECURE="false"3. 在 src/capabilities.ts 中注册
打开你的应用的 src/capabilities.ts,在 email 字段中配置你选择的提供商:
// src/capabilities.ts (你的应用 — apps/launchsaas/src/capabilities.ts)
// 选项 A — Resend(推荐)
import { ResendEmailProvider } from "@launchsaas/email-resend";
// 选项 B — Nodemailer (SMTP)
// import { NodemailerEmailProvider } from "@launchsaas/email-nodemailer";
export const capabilities = {
// 设为 null 即可禁用邮件功能
email: ResendEmailProvider.create(),
// email: NodemailerEmailProvider.create(),
// ...其他 capabilities
};4. 验证是否正常工作
启动开发服务器,触发一封邮件(例如注册获得验证邮件)。检查 Resend Dashboard 或 SMTP 日志。
Resend:域名验证(生产环境)
要从自己的域名发送邮件而非 Resend 测试地址:
- 前往 Resend Dashboard 的 Domains
- 点击 Add Domain 并输入你的域名(例如
yourdomain.com) - 将 Resend 提供的 DNS 记录(MX、TXT/SPF、DKIM)添加到你的 DNS 提供商
- 等待 DNS 传播(最多 48 小时),然后点击 Verify
- 更新环境变量:
RESEND_FROM_EMAIL="[email protected]"
电子邮件模板
LaunchSaaS 使用 packages/design-system/email-templates 中的共享 @launchsaas/email-templates 包渲染事务邮件。apps/email 只是 React Email 预览入口,会复用同一套共享布局,不维护单独的模板实现。生产邮件内容来自 messages/[locale].json 的 Email 命名空间:
| 模板 | 发送时机 |
|---|---|
emailVerification | 用户注册时 |
resetPassword | 密码重置流程 |
magicLink | 无密码登录 |
paymentCompleted | 支付确认 |
welcome | 验证完成后的欢迎邮件 |
i18n 支持
模板自动使用用户保存的语言(按以下顺序回退:请求语言 → 默认 en)。翻译定义在 messages/[locale].json 的 Email 命名空间下:
{
"Email": {
"hello": "你好,{name}",
"emailVerification": {
"title": "验证你的邮箱",
"heading": "邮箱验证",
"action": "验证邮箱",
"content": "请点击下面的按钮验证你的电子邮件地址。"
}
}
}预览模板
运行邮件预览应用即可在不发送真实邮件的情况下查看所有模板:
pnpm run dev:email
# → http://localhost:3003预览文件位于 apps/email/emails/。每个文件只提供 mock 数据,并渲染共享的完整邮件布局。
自定义邮件提供商
要集成 LaunchSaaS 未内置的提供商,可创建新的 email-xxx 包:
1. 创建包
mkdir -p packages/capabilities/email-myservice/srcpackages/capabilities/email-myservice/package.json:
{
"name": "@launchsaas/email-myservice",
"version": "0.1.0",
"private": true,
"main": "./src/index.ts",
"exports": {
".": "./src/index.ts"
},
"dependencies": {
"@launchsaas/email": "workspace:*",
"@launchsaas/errors": "workspace:*",
"@t3-oss/env-nextjs": "^0.13.10",
"my-email-sdk": "^1.0.0",
"zod": "^4.0.0"
}
}packages/capabilities/email-myservice/src/keys.ts:
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";
export const keys = createEnv({
server: {
MYSERVICE_API_KEY: z.string().optional(),
MYSERVICE_FROM_EMAIL: z.string().optional(),
},
experimental__runtimeEnv: {},
});packages/capabilities/email-myservice/src/provider.ts:
import type { EmailProvider, SendEmailOptions } from "@launchsaas/email";
export class MyServiceEmailProvider implements EmailProvider {
readonly name = "myservice";
static create(): MyServiceEmailProvider {
return new MyServiceEmailProvider();
}
async send(options: SendEmailOptions): Promise<void> {
// 在这里调用 my-email-sdk
}
}packages/capabilities/email-myservice/src/index.ts:
export { MyServiceEmailProvider } from "./provider";
export { keys } from "./keys";2. 在应用中接入
pnpm add @launchsaas/email-myservice将 keys 添加到 env.ts,并在你的应用的 src/capabilities.ts 中注册:
// src/capabilities.ts (apps/launchsaas/src/capabilities.ts)
import { MyServiceEmailProvider } from "@launchsaas/email-myservice";
export const capabilities = {
email: MyServiceEmailProvider.create(),
// ...其他 capabilities
};禁用邮件功能
若要完全禁用邮件功能,只需在 src/capabilities.ts 中将 email 字段设为 null。依赖邮件的功能(Magic Link、邮箱验证)会自动跳过。
如果禁用了邮件功能,建议同时在 features 配置中设置 magicLink: false,避免用户看到一个静默失败的登录选项。
提供商对比
| 提供商 | 包名 | 运行时 | 免费额度 |
|---|---|---|---|
| Resend | @launchsaas/email-resend | 任意(HTTP) | 100 封/天 |
| Nodemailer | @launchsaas/email-nodemailer | 仅 Node.js | 取决于 SMTP 服务商 |
| 自定义 | @launchsaas/email-xxx | 自定义 | — |