json-render-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.
基于React Email的渲染器,可将JSON规范转换为HTML或纯文本邮件输出。

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和catalog:
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
邮件元素规范
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和Catalog(无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
限制宽度(例如最大宽度600px)。
Section
内容分组;基于表格实现以保证兼容性。
Row
水平行。
Column
行内列;通过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
标题文本(支持h1–h6)。
Text
正文文本。
Link
超链接(支持text、href属性)。
Button
样式为按钮的CTA链接(支持text、href属性)。
Image
来自URL的图片(支持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最大宽度600px)。
  • 使用内联样式或React Email的style属性;多数客户端会移除
    <style>
    块。
  • 优先使用基于表格的布局(Section、Row、Column)以获得广泛的客户端支持。
  • 图片使用绝对URL;多数客户端在某些场景下会阻止相对URL或cid:引用。
  • 在多个客户端(Gmail、Outlook、Apple Mail)中进行测试;尽可能使用预览工具或类似Litmus的服务。