用于使用 React 组件构建 HTML 电子邮件模板、向应用程序添加可视化电子邮件编辑器(使用 React Email 可视化编辑器)、将电子邮件渲染为 HTML 或通过 Resend 发送电子邮件。涵盖欢迎邮件、密码重置、通知、订单确认、新闻通讯、事务性邮件以及可嵌入的电子邮件编辑器组件。
React Email
使用 React 组件构建和发送 HTML 电子邮件。一种基于组件的现代电子邮件开发方式,适用于所有主流电子邮件客户端。
安装
npm i react-email
或者创建一个新项目:
npx create-email@latest
cd react-email-starter
npm install
npm run dev
这适用于任何包管理器(npm、yarn、pnpm、bun)——请相应替换。
开发服务器运行在 localhost:3000,提供 emails 文件夹中模板的预览界面。
添加到现有项目
安装包并在 package.json 中添加脚本:
{
"scripts": {
"email": "email dev --dir emails --port 3000"
}
}
确保 emails 文件夹的路径相对于项目根目录。确保 tsconfig.json 包含对 JSX 的适当支持。
基本电子邮件模板
使用 Tailwind 组件进行样式设置,创建结构正确的电子邮件组件:
import {
Html,
Head,
Preview,
Body,
Container,
Heading,
Text,
Button,
Tailwind,
pixelBasedPreset
} from 'react-email';
interface WelcomeEmailProps {
name: string;
verificationUrl: string;
}
export default function WelcomeEmail({ name, verificationUrl }: WelcomeEmailProps) {
return (
<Html lang="en">
<Tailwind
config={{
presets: [pixelBasedPreset],
theme: {
extend: {
colors: {
brand: '#007bff',
},
},
},
}}
>
<Head />
<Body className="bg-gray-100 font-sans">
<Preview>Welcome - Verify your email</Preview>
<Container className="max-w-xl mx-auto p-5">
<Heading className="text-2xl text-gray-800">
Welcome!
</Heading>
<Text className="text-base text-gray-800">
Hi {name}, thanks for signing up!
</Text>
<Button
href={verificationUrl}
className="bg-brand text-white px-5 py-3 rounded block text-center no-underline box-border"
>
Verify Email
</Button>
</Container>
</Body>
</Tailwind>
</Html>
);
}
// Preview props for testing
WelcomeEmail.PreviewProps = {
name: 'John Doe',
verificationUrl: 'https://example.com/verify/abc123'
} satisfies WelcomeEmailProps;
export { WelcomeEmail };
行为准则
- 在迭代代码时,只更新用户要求的部分。保持其余部分不变。
- 如果用户要求使用媒体查询,请告知大多数电子邮件客户端不支持媒体查询,并建议采用其他方法。
- 不要在 TypeScript 代码中直接使用模板变量(如
{{name}})。而是直接引用底层属性。如果用户明确要求使用{{variableName}},请仅将 mustache 字符串放在 PreviewProps 中,切勿放在组件 JSX 中:
const EmailTemplate = (props) => {
return (
<h1>Hello, {props.variableName}!</h1>
);
}
EmailTemplate.PreviewProps = {
variableName: "{{variableName}}",
};
export default EmailTemplate;
- 切勿在组件结构中直接编写
{{variableName}}模式。如果用户坚持,请解释这会使模板无效。
核心组件
完整组件文档请参见 references/COMPONENTS.md。
核心结构:
Html- 根包装器,带有lang属性Head- 元元素、样式、字体Body- 主要内容包装器Container- 最外层居中包装器(内置max-width: 37.5em)。每封电子邮件仅使用一次。Section- 内部内容块(无内置最大宽度)。用于在Container内对内容进行分组。Row和Column- 多列布局Tailwind- 启用 Tailwind CSS 实用类
内容:
Preview- 收件箱预览文本,始终位于<Body>内部的第一位Heading- h1-h6 标题Text- 段落Button- 样式化的链接按钮(始终包含box-border)Link- 超链接Img- 图片(请参阅下面的静态文件部分)Hr- 水平分隔线
专用:
CodeBlock- 语法高亮代码CodeInline- 内联代码Markdown- 渲染 MarkdownFont- 自定义网页字体
编写代码之前
当用户请求电子邮件模板时,如果用户未提供以下信息,请首先提出澄清问题:
- 品牌颜色 - 询问主要品牌颜色(十六进制代码,如 #007bff)
- Logo - 询问是否有 Logo 文件及其格式(仅限 PNG/JPG - 如果为 SVG/WEBP 则发出警告)
- 风格偏好 - 专业、休闲或简约风格
- 生产 URL - 静态资产在生产环境中的托管位置?
静态文件和图片
目录结构
本地图片必须放置在 emails 目录下的 static 文件夹中:
project/
├── emails/
│ ├── welcome.tsx
│ └── static/ <-- 图片放在这里
│ └── logo.png
开发与生产 URL
使用以下模式使图片在开发预览和生产环境中都能正常工作:
const baseURL = process.env.NODE_ENV === "production"
? "https://cdn.example.com" // 用户的生产 CDN
: "";
export default function Email() {
return (
<Img
src={`${baseURL}/static/logo.png`}
alt="Logo"
width="150"
height="50"
/>
);
}
工作原理:
- 开发环境:
baseURL为空,因此 URL 为/static/logo.png- 由 React Email 的开发服务器提供 - 生产环境:
baseURL为 CDN 域名,因此 URL 为https://cdn.example.com/static/logo.png
重要提示: 始终询问用户的生产托管 URL。不要硬编码 localhost:3000。
样式设置
完整的样式文档(包括排版、布局模式、暗色模式和品牌一致性)请参见 references/STYLING.md。
关键规则
- 使用带有
pixelBasedPreset的Tailwind(电子邮件客户端不支持rem)。从react-email导入pixelBasedPreset。 - 切勿使用 flexbox 或 grid — 使用
Row/Column组件或表格进行布局。 - 避免使用 CSS/Tailwind 媒体查询(
sm:、md:、lg:、xl:)— 电子邮件客户端支持有限。 - 切勿使用主题选择器(
dark:、light:)— 不支持。 - 切勿使用 SVG 或 WEBP 图片 — 警告用户渲染问题。
- 始终指定边框类型(
border-solid、border-dashed等)— 电子邮件客户端不会继承边框类型。 - 对于单侧边框,先重置其他边框(
border-none border-l border-solid)。
必需类
| 组件 | 必需类 | 原因 |
|---|---|---|
Button |
box-border |
防止内边距溢出按钮宽度 |
Hr / 任何边框 |
border-solid(或 border-dashed 等) |
电子邮件客户端不继承边框类型 |
| 单侧边框 | border-none + 侧边 |
重置其他侧的默认边框 |
结构说明
- 使用 Tailwind CSS 时,始终在
<Tailwind>内部定义<Head /> <Preview>应始终是<Body>内部的第一个元素- 仅在
PreviewProps中包含组件实际使用的 props - 对已知尺寸的元素(Logo、图标)使用固定宽度/高度;对内容图片使用响应式尺寸(
w-full、h-auto)
渲染
转换为 HTML
import { render } from 'react-email';
import { WelcomeEmail } from './emails/welcome';
const html = await render(
<WelcomeEmail name="John" verificationUrl="https://example.com/verify" />
);
转换为纯文本
const text = await render(<WelcomeEmail name="John" verificationUrl="https://example.com/verify" />, { plainText: true });
发送
React Email 支持使用任何电子邮件服务提供商发送。完整的发送文档(包括 Resend、Nodemailer 和 SendGrid 示例)请参见 references/SENDING.md。
使用 Resend SDK 的快速示例:
import { Resend } from 'resend';
import { WelcomeEmail } from './emails/welcome';
const resend = new Resend(process.env.RESEND_API_KEY);
const { data, error } = await resend.emails.send({
from: 'Acme <onboarding@resend.dev>',
to: ['user@example.com'],
subject: 'Welcome to Acme',
react: <WelcomeEmail name="John" verificationUrl="https://example.com/verify" />
});
Resend Node SDK 自动处理 HTML 和纯文本渲染。
CLI 命令
react-email 包提供了一个 CLI,可通过 email 命令访问:
| 命令 | 描述 |
|---|---|
email dev --dir <path> --port <port> |
启动预览开发服务器(默认:./emails,端口 3000) |
email build --dir <path> |
构建预览应用以用于生产部署 |
email start |
运行构建后的预览应用 |
email export --outDir <path> --pretty --plainText --dir <path> |
将模板导出为静态 HTML 文件 |
email resend setup |
通过 API 密钥将 CLI 连接到您的 Resend 账户 |
email resend reset |
移除存储的 Resend API 密钥 |
国际化
完整的国际化文档请参见 references/I18N.md。React Email 支持三个库:next-intl、react-i18next 和 react-intl。
电子邮件编辑器
React Email 包含一个可视化编辑器(@react-email/editor),可嵌入到您的应用中。它基于 TipTap/ProseMirror 构建,生成可直接用于电子邮件的 HTML。
完整文档请参见 references/EDITOR.md,包括:
EmailEditor— 功能齐全的组件,包含气泡菜单、斜杠命令和主题StarterKit— 35 个以上电子邮件感知扩展(标题、列表、表格、列、按钮等)Inspector— 用于编辑样式的上下文侧边栏EmailTheming— 内置主题(basic、minimal),支持自定义 CSS 属性composeReactEmail— 将编辑器内容导出为可直接用于电子邮件的 HTML 和纯文本- 通过
EmailNode和EmailMark自定义扩展
快速示例:
import { EmailEditor, type EmailEditorRef } from '@react-email/editor';
import '@react-email/editor/themes/default.css';
import { useRef } from 'react';
export function MyEditor() {
const ref = useRef<EmailEditorRef>(null);
return (
<EmailEditor
ref={ref}
content="<p>Start typing...</p>"
theme="basic"
/>
);
}
常见模式
完整示例请参见 references/PATTERNS.md,包括:
- 密码重置电子邮件
- 带产品列表的订单确认
- 带代码块的通知电子邮件
- 多列布局
- 团队邀请电子邮件
电子邮件最佳实践
- 跨电子邮件客户端测试 - Gmail、Outlook、Apple Mail、Yahoo Mail
- 保持响应式 - 最大宽度约 600px,在移动设备上测试
- 使用绝对图片 URL - 托管在可靠的 CDN 上
- 编写有意义的替代文本 - 描述内容图片的目的和细节;对装饰性图片(分隔符、分割线、背景装饰)使用
alt=""。React Email 的<Img>默认使用alt=""。 - 提供纯文本版本 - 无障碍必需
- 保持文件大小在 102KB 以下 - Gmail 会截断更大的邮件
- 添加正确的 TypeScript 类型 - 为所有电子邮件 props 定义接口
- 包含预览 props - 添加
.PreviewProps用于开发测试 - 使用已验证的域名 - 用于生产环境的
from地址
无障碍
React Email 处理结构默认值;其余部分取决于内容。
React Email 免费提供的内容:
<Html>设置lang和dir(默认值:lang="en" dir="ltr"— 可根据区域设置覆盖)<Img>默认使用alt="",因此装饰性图片会被屏幕阅读器跳过<Markdown>使用role="presentation"渲染布局表格<Preview>还会发出一个<title>标签
运行 npm install react-email@latest 升级以获取这些默认值。
您仍需执行的操作(内容选择):
- 以单个
<Heading as="h1">开头,按顺序嵌套子标题,切勿跳级(非常短的短信风格电子邮件可以完全省略标题) - 对有意义的图片设置描述性
alt;对装饰性图片传递显式的alt=""— 切勿省略该属性 - 链接图片永远不是装饰性的。 当
<Img>位于<Link>或<Button>内部时,alt必须描述链接的目标位置 — 链接图片上的alt=""会使链接没有可访问的名称 - 编写描述目标位置的链接文本(
<Button>Read the report</Button>,而不是click here) - 达到 4.5:1 的文本对比度(WCAG AA);在暗色模式下预览
- 对于您手动构建的布局表格(在
<Markdown>外部),添加role="presentation" - 对于非英语电子邮件,传递区域设置:
<Html lang={locale} dir={isRTL ? 'rtl' : 'ltr'}>(参见 I18N.md)
完整的规则集、严重性排名和编写清单,请参见 email-best-practices 技能中的 无障碍参考。






