邮件系统
学习如何在 NEXTDEVKIT 中使用 React Email 发送邮件和管理时事通讯
NEXTDEVKIT 包含一个强大的邮件系统,基于 React Email 和 Resend 提供商构建,提供美观、响应式的邮件模板,支持国际化,完美适用于交易邮件、时事通讯和用户通信。
🏗️ 邮件系统架构
NEXTDEVKIT 的邮件系统结构如下:
src/
├── mail/
│ ├── index.ts # 主要邮件发送函数
│ ├── types.ts # 邮件接口和类型
│ ├── actions.ts # 时事通讯服务器操作
│ ├── templates/
│ │ ├── index.ts # 模板注册表
│ │ ├── forgot-password.tsx # 密码重置模板
│ │ ├── email-verification.tsx # 邮件验证模板
│ │ ├── newsletter-signup.tsx # 时事通讯注册模板
│ │ └── contact-form.tsx # 联系表单模板
│ ├── providers/
│ │ ├── index.ts # 提供商注册表
│ │ └── resend.ts # Resend 提供商
│ └── components/
│ ├── layout.tsx # 邮件布局组件
│ └── email-button.tsx # 邮件按钮组件
├── config/
│ └── index.ts # 邮件配置
└── messages/
├── en.json # 英文邮件翻译
└── zh.json # 中文邮件翻译
⚙️ 邮件配置
应用配置
邮件设置在 src/config/index.ts
中配置:
export const appConfig = {
mail: {
provider: "resend", // 邮件提供商
from: "noreply@nextdevkit.com", // 默认发送者地址
contact: "contact@nextdevkit.com", // 联系邮箱地址
},
// ... 其他配置
} as const;
环境变量
设置所需的环境变量:
# 对于 Resend
RESEND_API_KEY=re_your_resend_api_key
RESEND_AUDIENCE_ID=your_audience_id # 用于时事通讯
提供商设置
Resend 设置
-
创建 Resend 账户:
- 访问 resend.com
- 创建账户并验证您的域名
-
获取 API 密钥:
- 转到 API Keys 部分
- 创建具有发送权限的新 API 密钥
- 添加到您的环境变量
-
时事通讯设置(可选):
- 在 Resend 中创建受众
- 获取受众 ID 用于时事通讯功能
📧 邮件模板
可用模板
NEXTDEVKIT 包含预构建的邮件模板:
模板 | 描述 | 上下文属性 |
---|---|---|
forgotPassword | 密码重置 | name: string , url: string |
emailVerification | 邮件验证 | name: string , url: string |
newsletterSignup | 时事通讯确认 | name: string , unsubscribeUrl: string |
contactForm | 联系表单通知 | name: string , email: string , message: string |
模板结构
每个模板都是一个支持国际化的 React 组件:
import { Layout } from "@/mail/components/layout";
import { EmailButton } from "@/mail/components/email-button";
import type { i18nEmailProps } from "@/mail/types";
interface WelcomeEmailProps extends i18nEmailProps {
name: string;
}
export function Welcome({ name, locale, messages }: WelcomeEmailProps) {
const t = createTranslator({
locale,
messages,
namespace: "mail.welcome",
});
return (
<Layout>
<Text>{t("greeting", { name })}</Text>
<Text>{t("body")}</Text>
<EmailButton href="https://nextdevkit.com/docs">
{t("getStarted")}
</EmailButton>
</Layout>
);
}
模板注册表
模板在 src/mail/templates/index.ts
中注册:
export const mailTemplates = {
forgotPassword: ForgotPassword,
newsletterSignup: NewsletterSignup,
emailVerification: EmailVerification,
contactForm: ContactForm,
} as const;
export type TemplateKey = keyof typeof mailTemplates;
📤 发送邮件
基本邮件发送
使用 sendEmail
函数发送邮件:
import { sendEmail } from "@/mail";
// 使用模板发送
await sendEmail({
to: "user@example.com",
templateKey: "forgotPassword",
context: {
name: "John Doe",
url: "https://example.com/reset-password",
},
locale: "en", // 可选,默认为配置默认值
});
// 发送原始 HTML 邮件
await sendEmail({
to: "user@example.com",
subject: "欢迎使用 NEXTDEVKIT",
html: "<h1>欢迎!</h1><p>感谢您加入我们。</p>",
text: "欢迎!感谢您加入我们。",
});
服务器操作示例
"use server";
import { sendEmail } from "@/mail";
import { getSession } from "@/lib/auth/server";
export async function sendResetPasswordEmail(resetUrl: string) {
const session = await getSession();
if (!session?.user) {
throw new Error("未验证");
}
const success = await sendEmail({
to: session.user.email,
templateKey: "forgotPassword",
context: {
name: session.user.name || "用户",
url: resetUrl,
},
});
if (!success) {
throw new Error("发送重置密码邮件失败");
}
}
📰 时事通讯管理
时事通讯操作
NEXTDEVKIT 为时事通讯管理提供服务器操作:
import {
subscribeToNewsletter,
unsubscribeFromNewsletter,
isSubscribedToNewsletter
} from "@/mail/actions";
// 订阅时事通讯
await subscribeToNewsletter({ email: "user@example.com" });
// 取消订阅时事通讯
await unsubscribeFromNewsletter({ email: "user@example.com" });
// 检查订阅状态
const isSubscribed = await isSubscribedToNewsletter({ email: "user@example.com" });
🌐 国际化
邮件翻译
邮件翻译存储在消息文件中:
英文(messages/en.json
):
{
"mail": {
"forgotPassword": {
"subject": "Reset your password",
"greeting": "Hi {name}!",
"body": "Click the button below to reset your password.",
"resetPassword": "Reset Password"
},
"emailVerification": {
"subject": "Verify your email",
"greeting": "Hi {name}!",
"body": "Click the button below to verify your email address.",
"verifyEmail": "Verify Email"
}
}
}
中文(messages/zh.json
):
{
"mail": {
"forgotPassword": {
"subject": "重置密码",
"greeting": "你好 {name}!",
"body": "点击下面的按钮重置你的密码。",
"resetPassword": "重置密码"
},
"emailVerification": {
"subject": "验证邮箱",
"greeting": "你好 {name}!",
"body": "点击下面的按钮验证你的邮箱地址。",
"verifyEmail": "验证邮箱"
}
}
}
本地化邮件发送
// 发送本地化邮件
await sendEmail({
to: "user@example.com",
templateKey: "forgotPassword",
context: {
name: "张三",
url: "https://example.com/reset-password",
},
locale: "zh", // 中文语言
});
🔧 创建自定义模板
1. 创建模板组件
import { Text } from "@react-email/components";
import { createTranslator } from "use-intl/core";
import { Layout } from "@/mail/components/layout";
import { EmailButton } from "@/mail/components/email-button";
import type { i18nEmailProps } from "@/mail/types";
interface CustomTemplateProps extends i18nEmailProps {
userName: string;
actionUrl: string;
}
export function CustomTemplate({
userName,
actionUrl,
locale,
messages
}: CustomTemplateProps) {
const t = createTranslator({
locale,
messages,
namespace: "mail.customTemplate",
});
return (
<Layout>
<Text>{t("greeting", { name: userName })}</Text>
<Text>{t("body")}</Text>
<EmailButton href={actionUrl}>
{t("action")}
</EmailButton>
</Layout>
);
}
2. 注册模板
import { CustomTemplate } from "./custom-template";
export const mailTemplates = {
// ... 现有模板
customTemplate: CustomTemplate,
} as const;
3. 添加翻译
// messages/zh.json
{
"mail": {
"customTemplate": {
"subject": "自定义邮件主题",
"greeting": "你好 {name}!",
"body": "这是一个自定义邮件模板。",
"action": "执行操作"
}
}
}
4. 使用模板
await sendEmail({
to: "user@example.com",
templateKey: "customTemplate",
context: {
userName: "John Doe",
actionUrl: "https://nextdevkit.com/action",
},
});
🔌 自定义邮件提供商
创建自定义提供商
import type { MailProvider, SendParams } from "@/mail/types";
export class CustomMailProvider implements MailProvider {
private apiKey: string;
constructor() {
this.apiKey = process.env.CUSTOM_MAIL_API_KEY!;
}
async sendEmail(params: SendParams): Promise<void> {
const response = await fetch("https://api.customprovider.com/send", {
method: "POST",
headers: {
"Authorization": `Bearer ${this.apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
to: params.to,
subject: params.subject,
html: params.html,
text: params.text,
}),
});
if (!response.ok) {
throw new Error("发送邮件失败");
}
}
async subscribe(email: string): Promise<void> {
// 订阅时事通讯的实现
}
async unsubscribe(email: string): Promise<void> {
// 取消订阅时事通讯的实现
}
async isSubscribed(email: string): Promise<boolean> {
// 检查订阅状态的实现
return false;
}
}
注册提供商
import { CustomMailProvider } from "./custom-provider";
const providers = {
resend: ResendMailProvider,
custom: CustomMailProvider, // 添加自定义提供商
} as const;
更新配置
export const appConfig = {
mail: {
provider: "custom", // 使用自定义提供商
from: "noreply@nextdevkit.com",
contact: "contact@nextdevkit.com",
},
// ... 其他配置
};
🔗 相关资源
🎯 下一步
现在您了解了邮件系统,请探索这些相关功能: