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 : 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和catalog:
@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字符串 |
| 服务端:将规范转换为纯文本字符串 |
| 邮件元素规范 |
| 预构建的组件实现 |
| 目录定义(Zod属性) |
Sub-path Exports
子路径导出
| Path | Purpose |
|---|---|
| Full package |
| Schema and catalog only (no React) |
| Standard component definitions and types |
| Render functions only |
| 路径 | 用途 |
|---|---|
| 完整包 |
| 仅包含Schema和Catalog(无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. |
| 组件 | 描述 |
|---|---|
| 限制宽度(例如最大宽度600px)。 |
| 内容分组;基于表格实现以保证兼容性。 |
| 水平行。 |
| 行内列;通过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. |
| 组件 | 描述 |
|---|---|
| 标题文本(支持h1–h6)。 |
| 正文文本。 |
| 超链接(支持text、href属性)。 |
| 样式为按钮的CTA链接(支持text、href属性)。 |
| 来自URL的图片(支持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最大宽度600px)。
- 使用内联样式或React Email的style属性;多数客户端会移除块。
<style> - 优先使用基于表格的布局(Section、Row、Column)以获得广泛的客户端支持。
- 图片使用绝对URL;多数客户端在某些场景下会阻止相对URL或cid:引用。
- 在多个客户端(Gmail、Outlook、Apple Mail)中进行测试;尽可能使用预览工具或类似Litmus的服务。