关于 react-email
React Email 是用于用 React 组件构建 HTML 邮件的开发工具,面向邮件模板开发者。它提供组件、预览、导出和可嵌入的可视化编辑器。
主要功能
- 01用 React 组件构建邮件
- 02预览邮件模板
- 03导出 HTML 和纯文本
- 04提供可嵌入的可视化编辑器
适用场景
- 01构建欢迎或密码重置邮件
- 02在开发服务器中预览模板
- 03将模板导出为静态 HTML
- 04在应用中编辑邮件内容
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ resend/ react-email --skill react-email安装后在 Claude Code 中输入/react-email确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdTESTS.mdreferences/COMPONENTS.mdEDITOR.mdI18N.mdPATTERNS.mdSENDING.mdSTYLING.md详细介绍
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"
}
}
确保邮件文件夹的路径相对于项目根目录。确保 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- 自定义 Web 字体
编写代码前
用户请求创建邮件模板时,如果他们尚未提供以下信息,请先提出澄清问题:
- 品牌颜色 - 询问品牌主色(十六进制代码,例如 #007bff)
- Logo - 询问他们是否有 Logo 文件及其格式(仅支持 PNG/JPG;如果是 SVG/WEBP,请提醒他们)
- 风格偏好 - 专业、随意或简约的语气
- 生产环境 URL - 静态资源将在生产环境中的何处托管?
静态文件和图片
目录结构
本地图片必须放在邮件目录中的 static 文件夹内:
project/
├── emails/
│ ├── welcome.tsx
│ └── static/ <-- Images go here
│ └── logo.png
开发环境与生产环境 URL
使用以下模式,确保图片在开发预览和生产环境中都能正常显示:
const baseURL = process.env.NODE_ENV === "production"
? "https://cdn.example.com" // User's production 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中只包含组件实际使用的属性- 已知尺寸的元素(徽标、图标)使用固定宽度和高度;内容图片使用响应式尺寸(
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 <[email protected]>',
to: ['[email protected]'],
subject: 'Welcome to Acme',
react: <WelcomeEmail name="John" verificationUrl="https://example.com/verify" />
});
Resend Node SDK 会自动处理 HTML 和纯文本渲染。
CLI 命令
react-email 包提供了可通过 email 命令使用的 CLI:
| 命令 | 说明 |
|---|---|
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 key 将 CLI 连接到你的 Resend 账户 |
email resend reset | 移除已保存的 Resend API key |
国际化
完整的 i18n 文档请参阅 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 类型 - 为所有电子邮件属性定义接口
- 包含预览属性 - 添加
.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>阅读报告</Button>,而不是“点击这里”) - 确保文本对比度达到 4.5:1(WCAG AA);在深色模式下预览
- 对于手动构建的布局表格(不在
<Markdown>内),添加role="presentation" - 对于非英语电子邮件,传入区域设置:
<Html lang={locale} dir={isRTL ? 'rtl' : 'ltr'}>(参见 I18N.md)
完整规则集、严重程度排序和编写检查清单,请参阅 email-best-practices 技能中的无障碍访问参考。