react-email
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese@json-render/react-email
@json-render/react-email
React Email renderer that converts JSON specs into HTML or plain-text email output.
可将JSON规范转换为HTML或纯文本邮件输出的React Email渲染器。
Quick Start
快速开始
typescript
import { renderToHtml } from "@json-render/react-email";
import { schema, standardComponentDefinitions } from "@json-render/react-email";
import { defineCatalog } from "@json-render/core";
const catalog = defineCatalog(schema, {
components: standardComponentDefinitions,
});
const spec = {
root: "html-1",
elements: {
"html-1": { type: "Html", props: { lang: "en", dir: "ltr" }, children: ["head-1", "body-1"] },
"head-1": { type: "Head", props: {}, children: [] },
"body-1": {
type: "Body",
props: { style: { backgroundColor: "#f6f9fc" } },
children: ["container-1"],
},
"container-1": {
type: "Container",
props: { style: { maxWidth: "600px", margin: "0 auto", padding: "20px" } },
children: ["heading-1", "text-1"],
},
"heading-1": { type: "Heading", props: { text: "Welcome" }, children: [] },
"text-1": { type: "Text", props: { text: "Thanks for signing up." }, children: [] },
},
};
const html = await renderToHtml(spec);typescript
import { renderToHtml } from "@json-render/react-email";
import { schema, standardComponentDefinitions } from "@json-render/react-email";
import { defineCatalog } from "@json-render/core";
const catalog = defineCatalog(schema, {
components: standardComponentDefinitions,
});
const spec = {
root: "html-1",
elements: {
"html-1": { type: "Html", props: { lang: "en", dir: "ltr" }, children: ["head-1", "body-1"] },
"head-1": { type: "Head", props: {}, children: [] },
"body-1": {
type: "Body",
props: { style: { backgroundColor: "#f6f9fc" } },
children: ["container-1"],
},
"container-1": {
type: "Container",
props: { style: { maxWidth: "600px", margin: "0 auto", padding: "20px" } },
children: ["heading-1", "text-1"],
},
"heading-1": { type: "Heading", props: { text: "Welcome" }, children: [] },
"text-1": { type: "Text", props: { text: "Thanks for signing up." }, children: [] },
},
};
const html = await renderToHtml(spec);Spec Structure (Element Tree)
规范结构(元素树)
Same flat element tree as : key plus map. Root must be ; children of should be and . Use (e.g. max-width 600px) inside for client-safe layout.
@json-render/reactrootelementsHtmlHtmlHeadBodyContainerBody和使用相同的扁平元素树结构:包含键和映射表。根节点必须是;的子节点应为和。可在内部使用(比如设置最大宽度600px)来实现兼容各类邮件客户端的布局。
@json-render/reactrootelementsHtmlHtmlHeadBodyBodyContainerCreating a Catalog and Registry
创建目录与注册表
typescript
import { defineCatalog } from "@json-render/core";
import { schema, defineRegistry, renderToHtml } from "@json-render/react-email";
import { standardComponentDefinitions } from "@json-render/react-email/catalog";
import { Container, Heading, Text } from "@react-email/components";
import { z } from "zod";
const catalog = defineCatalog(schema, {
components: {
...standardComponentDefinitions,
Alert: {
props: z.object({
message: z.string(),
variant: z.enum(["info", "success", "warning"]).nullable(),
}),
slots: [],
description: "A highlighted message block",
},
},
actions: {},
});
const { registry } = defineRegistry(catalog, {
components: {
Alert: ({ props }) => (
<Container style={{ padding: 16, backgroundColor: "#eff6ff", borderRadius: 8 }}>
<Text style={{ margin: 0 }}>{props.message}</Text>
</Container>
),
},
});
const html = await renderToHtml(spec, { registry });typescript
import { defineCatalog } from "@json-render/core";
import { schema, defineRegistry, renderToHtml } from "@json-render/react-email";
import { standardComponentDefinitions } from "@json-render/react-email/catalog";
import { Container, Heading, Text } from "@react-email/components";
import { z } from "zod";
const catalog = defineCatalog(schema, {
components: {
...standardComponentDefinitions,
Alert: {
props: z.object({
message: z.string(),
variant: z.enum(["info", "success", "warning"]).nullable(),
}),
slots: [],
description: "A highlighted message block",
},
},
actions: {},
});
const { registry } = defineRegistry(catalog, {
components: {
Alert: ({ props }) => (
<Container style={{ padding: 16, backgroundColor: "#eff6ff", borderRadius: 8 }}>
<Text style={{ margin: 0 }}>{props.message}</Text>
</Container>
),
},
});
const html = await renderToHtml(spec, { registry });Server-Side Render APIs
服务端渲染API
| Function | Purpose |
|---|---|
| Render spec to HTML email string |
| Render spec to plain-text email string |
RenderOptionsregistryincludeStandardstate$state$cond| 函数 | 用途 |
|---|---|
| 将规范渲染为HTML邮件字符串 |
| 将规范渲染为纯文本邮件字符串 |
RenderOptionsregistryincludeStandardstate$state$condVisibility and State
可见性与状态
Supports conditions, , , repeat (), and the same expression syntax as . Use in when rendering server-side so expressions resolve.
visible$state$condrepeat.statePath@json-render/reactstateRenderOptions支持条件、、、重复(),以及和相同的表达式语法。服务端渲染时可在中传入来完成表达式解析。
visible$state$condrepeat.statePath@json-render/reactRenderOptionsstateServer-Safe Import
服务端安全导入
Import schema and catalog without React or :
@react-email/componentstypescript
import { schema, standardComponentDefinitions } from "@json-render/react-email/server";无需引入React或即可导入schema和目录:
@react-email/componentstypescript
import { schema, standardComponentDefinitions } from "@json-render/react-email/server";Key Exports
核心导出
| Export | Purpose |
|---|---|
| Create type-safe component registry from catalog |
| Render spec in browser (e.g. preview); use with |
| Standalone renderer component with state/actions/validation |
| Server: spec to HTML string |
| Server: spec to plain-text string |
| Email element schema |
| Pre-built component implementations |
| Catalog definitions (Zod props) |
| 导出项 | 用途 |
|---|---|
| 基于目录创建类型安全的组件注册表 |
| 在浏览器中渲染规范(如预览场景);需配合 |
| 内置状态/操作/校验的独立渲染器组件 |
| 服务端能力:将规范转为HTML字符串 |
| 服务端能力:将规范转为纯文本字符串 |
| 邮件元素schema |
| 预构建的组件实现 |
| 目录定义(Zod属性校验) |
Sub-path Exports
子路径导出
| Path | Purpose |
|---|---|
| Full package |
| Schema and catalog only (no React) |
| Standard component definitions and types |
| Render functions only |
| 路径 | 用途 |
|---|---|
| 完整包 |
| 仅包含schema和目录(无React依赖) |
| 标准组件定义和类型 |
| 仅包含渲染函数 |
Standard Components
标准组件
All components accept a prop (object) for inline styles. Use inline styles for email client compatibility; avoid external CSS.
style所有组件都支持属性(对象格式)用于设置行内样式。为了兼容邮件客户端,请使用行内样式,避免使用外部CSS。
styleDocument structure
文档结构
| Component | Description |
|---|---|
| Root wrapper (lang, dir). Children: Head, Body. |
| Email head section. |
| Body wrapper; use |
| 组件 | 描述 |
|---|---|
| 根容器(支持设置lang、dir属性),子节点为Head、Body |
| 邮件头部区域 |
| 内容容器,可通过 |
Layout
布局组件
| Component | Description |
|---|---|
| Constrain width (e.g. max-width 600px). |
| Group content; table-based for compatibility. |
| Horizontal row. |
| Column in a Row; set width via style. |
| 组件 | 描述 |
|---|---|
| 限制内容宽度(比如设置max-width 600px) |
| 内容分组,基于表格实现,兼容性好 |
| 水平行 |
| Row内的列,可通过style设置宽度 |
Content
内容组件
| Component | Description |
|---|---|
| Heading text (as: h1–h6). |
| Body text. |
| Hyperlink (text, href). |
| CTA link styled as button (text, href). |
| Image from URL (src, alt, width, height). |
| Horizontal rule. |
| 组件 | 描述 |
|---|---|
| 标题文本(支持as属性设置为h1–h6) |
| 正文文本 |
| 超链接(支持text、href属性) |
| 按钮样式的CTA链接(支持text、href属性) |
| 外链图片(支持src、alt、width、height属性) |
| 水平分割线 |
Utility
工具组件
| Component | Description |
|---|---|
| Inbox preview text (inside Html). |
| Markdown content as email-safe HTML. |
| 组件 | 描述 |
|---|---|
| 收件箱预览文本(放置在Html节点内) |
| 将Markdown内容转为邮件安全的HTML格式 |
Email Best Practices
邮件开发最佳实践
- Keep width constrained (e.g. Container max-width 600px).
- Use inline styles or React Email's style props; many clients strip blocks.
<style> - Prefer table-based layout (Section, Row, Column) for broad client support.
- Use absolute URLs for images; many clients block relative or cid: references in some contexts.
- Test in multiple clients (Gmail, Outlook, Apple Mail); use a preview tool or Litmus-like service when possible.
- 限制内容宽度(比如Container设置max-width 600px)。
- 使用行内样式或React Email的样式属性;很多邮件客户端会移除块。
<style> - 优先使用基于表格的布局(Section、Row、Column)以适配更多客户端。
- 图片使用绝对URL;很多客户端在部分场景下会屏蔽相对路径或cid:引用的资源。
- 在多个客户端中测试(Gmail、Outlook、Apple Mail);尽可能使用预览工具或类似Litmus的服务进行测试。