react-email
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseReact Email
React Email
Build and send HTML emails using React components. A modern, component-based approach to email development that works across all major email clients.
使用 React 组件构建并发送 HTML 邮件。一种现代化、基于组件的邮件开发方式,兼容所有主流邮件客户端。
Installation
安装
sh
npm i react-emailOr scaffold a new project:
sh
npx create-email@latest
cd react-email-starter
npm install
npm run devThis works with any package manager (npm, yarn, pnpm, bun) — substitute accordingly.
The dev server runs at localhost:3000 with a preview interface for templates in the folder.
emailssh
npm i react-email或者搭建新项目:
sh
npx create-email@latest
cd react-email-starter
npm install
npm run dev这适用于任何包管理器(npm、yarn、pnpm、bun)——请相应替换命令。
开发服务器运行在 localhost:3000,并为 文件夹中的模板提供预览界面。
emailsAdding to an Existing Project
添加到现有项目
Install the packages and add a script to your :
package.jsonjson
{
"scripts": {
"email": "email dev --dir emails --port 3000"
}
}Make sure the path to the emails folder is relative to the base project directory. Ensure includes proper support for JSX.
tsconfig.json安装这些包,并向 添加脚本:
package.jsonjson
{
"scripts": {
"email": "email dev --dir emails --port 3000"
}
}确保 文件夹的路径相对于项目根目录。确保 正确支持 JSX。
emailstsconfig.jsonBasic Email Template
基本邮件模板
Create an email component with proper structure using the Tailwind component for styling:
tsx
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 };使用用于样式设置的 组件,以正确的结构创建邮件组件:
Tailwindtsx
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 };Behavioral Guidelines
行为准则
- When iterating over the code, only update what the user asked for. Keep the rest intact.
- If the user asks to use media queries, inform them that most email clients don't support them and suggest a different approach.
- Never use template variables (like ) directly in TypeScript code. Instead, reference the underlying properties directly. If the user explicitly asks for
{{name}}, place the mustache string only in PreviewProps, never in the component JSX:{{variableName}}
typescript
const EmailTemplate = (props) => {
return (
<h1>Hello, {props.variableName}!</h1>
);
}
EmailTemplate.PreviewProps = {
variableName: "{{variableName}}",
};
export default EmailTemplate;- Never write the pattern directly in the component structure. If the user insists, explain that this would make the template invalid.
{{variableName}}
- 修改代码时,仅更新用户要求的内容,其余部分保持不变。
- 如果用户要求使用 media queries,请告知大多数邮件客户端不支持它们,并建议采用其他方案。
- 绝不要在 TypeScript 代码中直接使用模板变量(如 ),而应直接引用底层属性。如果用户明确要求使用
{{name}},则仅将 mustache 字符串放在{{variableName}}中,绝不要放在组件 JSX 中:PreviewProps
typescript
const EmailTemplate = (props) => {
return (
<h1>Hello, {props.variableName}!</h1>
);
}
EmailTemplate.PreviewProps = {
variableName: "{{variableName}}",
};
export default EmailTemplate;- 绝不要直接在组件结构中编写 模式。如果用户坚持这样做,请解释这会导致模板无效。
{{variableName}}
Essential Components
核心组件
See references/COMPONENTS.md for complete component documentation.
Core Structure:
- - Root wrapper with
Htmlattributelang - - Meta elements, styles, fonts
Head - - Main content wrapper
Body - - Outermost centering wrapper (has built-in
Container). Use only once per email.max-width: 37.5em - - Interior content blocks (no built-in max-width). Use for grouping content inside
Section.Container - &
Row- Multi-column layoutsColumn - - Enables Tailwind CSS utility classes
Tailwind
Content:
- - Inbox preview text, always first inside
Preview<Body> - - h1-h6 headings
Heading - - Paragraphs
Text - - Styled link buttons (always include
Button)box-border - - Hyperlinks
Link - - Images (see Static Files section below)
Img - - Horizontal dividers
Hr
Specialized:
- - Syntax-highlighted code
CodeBlock - - Inline code
CodeInline - - Render markdown
Markdown - - Custom web fonts
Font
有关完整的组件文档,请参阅 references/COMPONENTS.md。
核心结构:
- - 带
Html属性的根包装器lang - - 元元素、样式和字体
Head - - 主要内容包装器
Body - - 最外层居中包装器(内置
Container)。每封邮件仅使用一次。max-width: 37.5em - - 内部内容区块(没有内置 max-width)。用于在
Section内组织内容。Container - 与
Row- 多列布局Column - - 启用 Tailwind CSS 工具类
Tailwind
内容:
- - 收件箱预览文本,始终位于
Preview内的第一个位置<Body> - - h1-h6 标题
Heading - - 段落
Text - - 带样式的链接按钮(始终包含
Button)box-border - - 超链接
Link - - 图片(参见下方的静态文件部分)
Img - - 水平分隔线
Hr
专用组件:
- - 带语法高亮的代码块
CodeBlock - - 行内代码
CodeInline - - 渲染 Markdown
Markdown - - 自定义 Web 字体
Font
Before Writing Code
编写代码前
When a user requests an email template, ask clarifying questions FIRST if they haven't provided:
- Brand colors - Ask for primary brand color (hex code like #007bff)
- Logo - Ask if they have a logo file and its format (PNG/JPG only - warn if SVG/WEBP)
- Style preference - Professional, casual, or minimal tone
- Production URL - Where will static assets be hosted in production?
当用户请求邮件模板,但尚未提供以下信息时,请先提出澄清问题:
- 品牌颜色 - 询问主要品牌颜色(十六进制代码,如 #007bff)
- Logo - 询问用户是否有 Logo 文件及其格式(仅限 PNG/JPG——如果使用 SVG/WEBP,则提醒用户)
- 风格偏好 - 专业、休闲或极简风格
- 生产环境 URL - 生产环境中的静态资源将托管在哪里?
Static Files and Images
静态文件与图片
Directory Structure
目录结构
Local images must be placed in the folder inside your emails directory:
staticproject/
├── emails/
│ ├── welcome.tsx
│ └── static/ <-- Images go here
│ └── logo.png本地图片必须放在 目录内的 文件夹中:
emailsstaticproject/
├── emails/
│ ├── welcome.tsx
│ └── static/ <-- Images go here
│ └── logo.pngDev vs Production URLs
开发与生产环境 URL
Use this pattern for images that work in both dev preview and production:
tsx
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"
/>
);
}How it works:
- Development: is empty, so URL is
baseURL- served by React Email's dev server/static/logo.png - Production: is the CDN domain, so URL is
baseURLhttps://cdn.example.com/static/logo.png
Important: Always ask the user for their production hosting URL. Do not hardcode .
localhost:3000使用以下模式处理可同时用于开发预览和生产环境的图片:
tsx
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"
/>
);
}工作方式:
- 开发环境: 为空,因此 URL 为
baseURL——由 React Email 的开发服务器提供/static/logo.png - 生产环境: 为 CDN 域名,因此 URL 为
baseURLhttps://cdn.example.com/static/logo.png
重要提示: 始终向用户询问其生产环境托管 URL。不要硬编码 。
localhost:3000Styling
样式
See references/STYLING.md for comprehensive styling documentation including typography, layout patterns, dark mode, and brand consistency.
有关排版、布局模式、深色模式和品牌一致性等全面样式文档,请参阅 references/STYLING.md。
Key Rules
关键规则
- Use with
Tailwind(email clients don't supportpixelBasedPreset). ImportremfrompixelBasedPreset.react-email - Never use flexbox or grid — use /
Rowcomponents or tables for layouts.Column - Avoid CSS/Tailwind media queries (,
sm:,md:,lg:) — limited email client support.xl: - Never use theme selectors (,
dark:) — not supported.light: - Never use SVG or WEBP images — warn users about rendering issues.
- Always specify border type (,
border-solid, etc.) — email clients don't inherit it.border-dashed - For single-side borders, reset others first ().
border-none border-l border-solid
- 使用 和
Tailwind(邮件客户端不支持pixelBasedPreset)。从rem导入react-email。pixelBasedPreset - 绝不要使用 flexbox 或 grid——使用 /
Row组件或表格进行布局。Column - 避免使用 CSS/Tailwind media queries(、
sm:、md:、lg:)——邮件客户端对其支持有限。xl: - 绝不要使用主题选择器(、
dark:)——不受支持。light: - 绝不要使用 SVG 或 WEBP 图片——提醒用户可能存在渲染问题。
- 始终指定边框类型(、
border-solid等)——邮件客户端不会继承边框类型。border-dashed - 对于单侧边框,先重置其他边框()。
border-none border-l border-solid
Required Classes
必需类名
| Component | Required Class | Why |
|---|---|---|
| | Prevents padding from overflowing the button width |
| | Email clients don't inherit border type |
| Single-side borders | | Resets default borders on other sides |
| 组件 | 必需类名 | 原因 |
|---|---|---|
| | 防止内边距溢出按钮宽度 |
| | 邮件客户端不会继承边框类型 |
| 单侧边框 | | 重置其他侧默认边框 |
Structure Notes
结构说明
- Always define inside
<Head />when using Tailwind CSS<Tailwind> - should always be the first element inside
<Preview><Body> - Only include props in that the component actually uses
PreviewProps - Use fixed width/height for known-size elements (logos, icons); responsive sizing (,
w-full) for content imagesh-auto
- 使用 Tailwind CSS 时,始终在 内定义
<Tailwind><Head /> - 应始终是
<Preview>内的第一个元素<Body> - 中只包含组件实际使用的属性
PreviewProps - 对尺寸已知的元素(Logo、图标)使用固定宽高;对内容图片使用响应式尺寸(、
w-full)h-auto
Rendering
渲染
Convert to HTML
转换为 HTML
tsx
import { render } from 'react-email';
import { WelcomeEmail } from './emails/welcome';
const html = await render(
<WelcomeEmail name="John" verificationUrl="https://example.com/verify" />
);tsx
import { render } from 'react-email';
import { WelcomeEmail } from './emails/welcome';
const html = await render(
<WelcomeEmail name="John" verificationUrl="https://example.com/verify" />
);Convert to Plain Text
转换为纯文本
tsx
const text = await render(<WelcomeEmail name="John" verificationUrl="https://example.com/verify" />, { plainText: true });tsx
const text = await render(<WelcomeEmail name="John" verificationUrl="https://example.com/verify" />, { plainText: true });Sending
发送
React Email supports sending with any email service provider. See references/SENDING.md for complete sending documentation including Resend, Nodemailer, and SendGrid examples.
Quick example using the Resend SDK:
tsx
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" />
});The Resend Node SDK automatically handles both HTML and plain-text rendering.
React Email 支持通过任意邮件服务提供商发送邮件。有关完整的发送文档,包括 Resend、Nodemailer 和 SendGrid 示例,请参阅 references/SENDING.md。
使用 Resend SDK 的快速示例:
tsx
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 Commands
CLI 命令
The package provides a CLI accessible via the command:
react-emailemail| Command | Description |
|---|---|
| Start the preview development server (default: |
| Build the preview app for production deployment |
| Run the built preview app |
| Export templates to static HTML files |
| Connect the CLI to your Resend account via API key |
| Remove the stored Resend API key |
react-emailemail| 命令 | 说明 |
|---|---|
| 启动预览开发服务器(默认目录为 |
| 构建用于生产部署的预览应用 |
| 运行已构建的预览应用 |
| 将模板导出为静态 HTML 文件 |
| 通过 API 密钥将 CLI 连接到你的 Resend 账户 |
| 删除已存储的 Resend API 密钥 |
Internationalization
国际化
See references/I18N.md for complete i18n documentation. React Email supports three libraries: next-intl, react-i18next, and react-intl.
有关完整的 i18n 文档,请参阅 references/I18N.md。React Email 支持三个库:next-intl、react-i18next 和 react-intl。
Email Editor
邮件编辑器
React Email includes a visual editor () that can be embedded in your app. It's built on TipTap/ProseMirror and produces email-ready HTML.
@react-email/editorSee references/EDITOR.md for complete documentation including:
- — batteries-included component with bubble menus, slash commands, and theming
EmailEditor - — 35+ email-aware extensions (headings, lists, tables, columns, buttons, etc.)
StarterKit - — contextual sidebar for editing styles
Inspector - — built-in themes (
EmailTheming,basic) with customizable CSS propertiesminimal - — export editor content to email-ready HTML and plain text
composeReactEmail - Custom extensions via and
EmailNodeEmailMark
Quick example:
tsx
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"
/>
);
}React Email 包含一个可嵌入应用的可视化编辑器()。它基于 TipTap/ProseMirror 构建,可生成适合邮件使用的 HTML。
@react-email/editor有关完整文档,请参阅 references/EDITOR.md,其中包括:
- — 开箱即用的组件,带气泡菜单、斜杠命令和主题功能
EmailEditor - — 35+ 个面向邮件场景的扩展(标题、列表、表格、分栏、按钮等)
StarterKit - - 用于编辑样式的上下文侧边栏
Inspector - - 内置主题(
EmailTheming、basic),可自定义 CSS 属性minimal - - 将编辑器内容导出为适合邮件使用的 HTML 和纯文本
composeReactEmail - 通过 和
EmailNode使用自定义扩展EmailMark
快速示例:
tsx
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"
/>
);
}Common Patterns
常见模式
See references/PATTERNS.md for complete examples including:
- Password reset emails
- Order confirmations with product lists
- Notification emails with code blocks
- Multi-column layouts
- Team invitation emails
有关完整示例,请参阅 references/PATTERNS.md,其中包括:
- 密码重置邮件
- 带商品列表的订单确认邮件
- 包含代码块的通知邮件
- 多列布局
- 团队邀请邮件
Email Best Practices
邮件最佳实践
- Test across email clients - Gmail, Outlook, Apple Mail, Yahoo Mail
- Keep it responsive - Max-width around 600px, test on mobile
- Use absolute image URLs - Host on reliable CDN
- Write meaningful alt text - Describe purpose and details for content images; use for decorative images (spacers, dividers, background flourishes). React Email's
alt=""defaults to<Img>.alt="" - Provide plain text version - Required for accessibility
- Keep file size under 102KB - Gmail clips larger emails
- Add proper TypeScript types - Define interfaces for all email props
- Include preview props - Add for development testing
.PreviewProps - Use verified domains - For production addresses
from
- 在多个邮件客户端中测试 - Gmail、Outlook、Apple Mail、Yahoo Mail
- 保持响应式设计 - 最大宽度约为 600px,并在移动端测试
- 使用绝对图片 URL - 托管在可靠的 CDN 上
- 编写有意义的替代文本 - 描述内容图片的用途和细节;装饰性图片(间隔块、分隔线、背景装饰)使用 。React Email 的
alt=""默认使用<Img>。alt="" - 提供纯文本版本 - 无障碍访问所必需
- 将文件大小控制在 102KB 以下 - Gmail 会截断更大的邮件
- 添加正确的 TypeScript 类型 - 为所有邮件属性定义接口
- 包含预览属性 - 添加 以便在开发环境中测试
.PreviewProps - 使用已验证的域名 - 用于生产环境的发件人地址
Accessibility
无障碍访问
React Email handles the structural defaults; the rest is content.
What React Email gives you for free:
- sets
<Html>andlang(defaults:dir— override per locale)lang="en" dir="ltr" - defaults to
<Img>so decorative images are skipped by screen readersalt="" - renders layout tables with
<Markdown>role="presentation" - also emits a
<Preview>tag<title>
Upgrade with to get these defaults.
npm install react-email@latestWhat you still have to do (content choices):
- Open with a single , nest subheadings in order, never skip levels (very short SMS-style emails may skip the heading entirely)
<Heading as="h1"> - Set descriptive on meaningful images; pass an explicit
alton decorative images — never omit the attributealt="" - Linked images are never decorative. When an is inside a
<Img>or<Link>, the<Button>must describe where the link goes —alton a linked image leaves the link with no accessible namealt="" - Write link text that describes the destination (, not
<Button>Read the report</Button>)click here - Hit 4.5:1 text contrast (WCAG AA); preview in dark mode
- For layout tables you build by hand (outside ), add
<Markdown>role="presentation" - For non-English emails, pass the locale: (see I18N.md)
<Html lang={locale} dir={isRTL ? 'rtl' : 'ltr'}>
For the full rule set, severity ranking, and authoring checklist, see the accessibility reference in the skill.
email-best-practicesReact Email 会处理结构性默认值,其余部分取决于内容。
React Email 默认提供:
- 设置
<Html>和lang(默认值为dir——可按语言环境覆盖)lang="en" dir="ltr" - 默认使用
<Img>,因此屏幕阅读器会跳过装饰性图片alt="" - 使用
<Markdown>渲染布局表格role="presentation" - 还会输出
<Preview>标签<title>
通过 升级即可获得这些默认行为。
npm install react-email@latest仍需由你完成的部分(内容选择):
- 以单个 开头,按顺序嵌套子标题,不要跳级(非常简短的 SMS 风格邮件可以完全省略标题)
<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" - 对于非英语邮件,传入语言环境:(参见 I18N.md)
<Html lang={locale} dir={isRTL ? 'rtl' : 'ltr'}>
有关完整的规则集、严重程度排名和编写检查清单,请参阅 skill 中的无障碍访问参考。
email-best-practicesAdditional Resources
其他资源
- React Email Documentation
- React Email GitHub
- Resend Documentation
- Email Client CSS Support
- Component Reference: references/COMPONENTS.md
- Styling Guide: references/STYLING.md
- Email Editor: references/EDITOR.md
- Sending Guide: references/SENDING.md
- Internationalization Guide: references/I18N.md
- Common Patterns: references/PATTERNS.md
- React Email 文档
- React Email GitHub
- Resend 文档
- 邮件客户端 CSS 支持
- 组件参考:references/COMPONENTS.md
- 样式指南:references/STYLING.md
- 邮件编辑器:references/EDITOR.md
- 发送指南:references/SENDING.md
- 国际化指南:references/I18N.md
- 常见模式:references/PATTERNS.md