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
@json-render/react
:
root
key plus
elements
map. Root must be
Html
; children of
Html
should be
Head
and
Body
. Use
Container
(e.g. max-width 600px) inside
Body
for client-safe layout.
@json-render/react
使用相同的扁平元素树结构:包含
root
键和
elements
映射表。根节点必须是
Html
Html
的子节点应为
Head
Body
。可在
Body
内部使用
Container
(比如设置最大宽度600px)来实现兼容各类邮件客户端的布局。

Creating 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

FunctionPurpose
renderToHtml(spec, options?)
Render spec to HTML email string
renderToPlainText(spec, options?)
Render spec to plain-text email string
RenderOptions
:
registry
,
includeStandard
(default true),
state
(for
$state
/
$cond
).
函数用途
renderToHtml(spec, options?)
将规范渲染为HTML邮件字符串
renderToPlainText(spec, options?)
将规范渲染为纯文本邮件字符串
RenderOptions
支持参数:
registry
includeStandard
(默认值为true)、
state
(用于
$state
/
$cond
逻辑)。

Visibility and State

可见性与状态

Supports
visible
conditions,
$state
,
$cond
, repeat (
repeat.statePath
), and the same expression syntax as
@json-render/react
. Use
state
in
RenderOptions
when rendering server-side so expressions resolve.
支持
visible
条件、
$state
$cond
、重复(
repeat.statePath
),以及和
@json-render/react
相同的表达式语法。服务端渲染时可在
RenderOptions
中传入
state
来完成表达式解析。

Server-Safe Import

服务端安全导入

Import schema and catalog without React or
@react-email/components
:
typescript
import { schema, standardComponentDefinitions } from "@json-render/react-email/server";
无需引入React或
@react-email/components
即可导入schema和目录:
typescript
import { schema, standardComponentDefinitions } from "@json-render/react-email/server";

Key Exports

核心导出

ExportPurpose
defineRegistry
Create type-safe component registry from catalog
Renderer
Render spec in browser (e.g. preview); use with
JSONUIProvider
for state/actions
createRenderer
Standalone renderer component with state/actions/validation
renderToHtml
Server: spec to HTML string
renderToPlainText
Server: spec to plain-text string
schema
Email element schema
standardComponents
Pre-built component implementations
standardComponentDefinitions
Catalog definitions (Zod props)
导出项用途
defineRegistry
基于目录创建类型安全的组件注册表
Renderer
在浏览器中渲染规范(如预览场景);需配合
JSONUIProvider
使用以支持状态/操作
createRenderer
内置状态/操作/校验的独立渲染器组件
renderToHtml
服务端能力:将规范转为HTML字符串
renderToPlainText
服务端能力:将规范转为纯文本字符串
schema
邮件元素schema
standardComponents
预构建的组件实现
standardComponentDefinitions
目录定义(Zod属性校验)

Sub-path Exports

子路径导出

PathPurpose
@json-render/react-email
Full package
@json-render/react-email/server
Schema and catalog only (no React)
@json-render/react-email/catalog
Standard component definitions and types
@json-render/react-email/render
Render functions only
路径用途
@json-render/react-email
完整包
@json-render/react-email/server
仅包含schema和目录(无React依赖)
@json-render/react-email/catalog
标准组件定义和类型
@json-render/react-email/render
仅包含渲染函数

Standard Components

标准组件

All components accept a
style
prop (object) for inline styles. Use inline styles for email client compatibility; avoid external CSS.
所有组件都支持
style
属性(对象格式)用于设置行内样式。为了兼容邮件客户端,请使用行内样式,避免使用外部CSS。

Document structure

文档结构

ComponentDescription
Html
Root wrapper (lang, dir). Children: Head, Body.
Head
Email head section.
Body
Body wrapper; use
style
for background.
组件描述
Html
根容器(支持设置lang、dir属性),子节点为Head、Body
Head
邮件头部区域
Body
内容容器,可通过
style
设置背景

Layout

布局组件

ComponentDescription
Container
Constrain width (e.g. max-width 600px).
Section
Group content; table-based for compatibility.
Row
Horizontal row.
Column
Column in a Row; set width via style.
组件描述
Container
限制内容宽度(比如设置max-width 600px)
Section
内容分组,基于表格实现,兼容性好
Row
水平行
Column
Row内的列,可通过style设置宽度

Content

内容组件

ComponentDescription
Heading
Heading text (as: h1–h6).
Text
Body text.
Link
Hyperlink (text, href).
Button
CTA link styled as button (text, href).
Image
Image from URL (src, alt, width, height).
Hr
Horizontal rule.
组件描述
Heading
标题文本(支持as属性设置为h1–h6)
Text
正文文本
Link
超链接(支持text、href属性)
Button
按钮样式的CTA链接(支持text、href属性)
Image
外链图片(支持src、alt、width、height属性)
Hr
水平分割线

Utility

工具组件

ComponentDescription
Preview
Inbox preview text (inside Html).
Markdown
Markdown content as email-safe HTML.
组件描述
Preview
收件箱预览文本(放置在Html节点内)
Markdown
将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
    <style>
    blocks.
  • 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的服务进行测试。