mcpField
R
react-email

react-email

github.com/resend设计与 UI20712.9k 次安装2 周前更新
代码仓库

关于 react-email

React Email 技能指导开发者使用 React 组件构建、预览和导出 HTML 邮件,也可生成纯文本版本。它提供组件库、CLI 和可嵌入的可视化编辑器。

主要功能

  1. 01用 React 组件构建邮件
  2. 02本地预览邮件模板
  3. 03导出 HTML 和纯文本
  4. 04提供邮件专用组件
  5. 05嵌入可视化邮件编辑器
  6. 06支持邮件国际化

适用场景

  1. 01制作密码重置和订单确认邮件
  2. 02预览并调整邮件模板
  3. 03将模板导出为静态文件
  4. 04在应用中加入邮件编辑器

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/resend/resend-skills --skill react-email

安装后在 Claude Code 中输入/react-email确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
COMPONENTS.md
EDITOR.md
I18N.md
PATTERNS.md
SENDING.md
STYLING.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 - 渲染 Markdown
  • Font - 自定义 Web 字体

编写代码前

用户请求创建邮件模板时,如果他们尚未提供以下信息,请先提出澄清问题:

  1. 品牌颜色 - 询问品牌主色(十六进制代码,例如 #007bff)
  2. Logo - 询问他们是否有 Logo 文件及其格式(仅支持 PNG/JPG;如果是 SVG/WEBP,请提醒他们)
  3. 风格偏好 - 专业、随意或简约的语气
  4. 生产环境 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)。
必需的类
组件必需的类原因
Buttonbox-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,包括:

  • 密码重置邮件
  • 含商品列表的订单确认邮件
  • 含代码块的通知邮件
  • 多栏布局
  • 团队邀请邮件

电子邮件最佳实践

  1. 在不同的电子邮件客户端中测试 - Gmail、Outlook、Apple Mail、Yahoo Mail
  2. 保持响应式 - 最大宽度约为 600px,并在移动设备上测试
  3. 使用绝对图片 URL - 托管在可靠的 CDN 上
  4. 编写有意义的替代文本 - 描述内容图片的用途和细节;装饰性图片(间隔图、分隔线、背景装饰)使用 alt=""。React Email 的 <Img> 默认使用 alt=""。
  5. 提供纯文本版本 - 无障碍访问所必需
  6. 将文件大小控制在 102KB 以下 - Gmail 会截断较大的电子邮件
  7. 添加适当的 TypeScript 类型 - 为所有电子邮件属性定义接口
  8. 包含预览属性 - 添加 .PreviewProps,用于开发测试
  9. 使用经过验证的域名 - 用于生产环境的 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 技能中的无障碍访问参考。

更多资源

评论

支持 Markdown