反应
编辑器作为组件挂载在你的树中。你的路由器、提供者和认证上下文仍然会包裹它,它的状态会像其他组件一样流回 React。
26k+
GitHub 在编辑器核心上加星
1.4M+
NPM每月下载量
100+
GJS.Market 上的插件和预设
BSD-3-Clause
编辑器核心的许可
不是租用的托管编辑器,也不是模板画廊。而是你在已经运行的应用里挂载的编辑层。
编辑器作为组件挂载在你的树中。你的路由器、提供者和认证上下文仍然会包裹它,它的状态会像其他组件一样流回 React。
用户通过选择模块并在文本位置编辑来组装邮件,而不是向开发人员描述布局或手工应对表格标记。
组件、模块、面板和命令都可以由你自己定义。针对你产品的编辑体验部分可以由你自己编写。
模板通过你自己的API保存到你的数据库,然后由你已经付费的供应商发送。这里没有调用编辑器服务在运行时。
这个画布是运行在本页上的React组件——没有编辑器包,没有iframe。添加一个块,点击任意部分选择,重新输入文本,重新设计,重新排序,并在桌面、平板和移动端切换预览。打开HTML标签页,查看邮件生成器反馈给代码的标记类型。
方块
在邮件中添加一部分。
点击某一部分选择,然后编辑或重新设计
选择
没有选择
点击画布中的一个部分,或者从方块面板添加一个。
以下内容在你要求之前不会加载:本页HTML中没有iframe,且一次只挂载一个演示。这些是由作者托管的公开演示。
新闻通讯预设:邮件安全块、受限样式管理器和基于表格的输出。这是最接近用户能看到的功能。
React 邮件构建器是一种运行在 React 应用中的可视化编辑器,允许用户创建和定制邮件模板,而无需手动编写 HTML 邮件标记。它不是用户登录的独立产品:它是应用中的一个组件,因此模板、拥有它们的账户以及发送这些模板的基础设施都会留在你这边。
穿过它的是什么
编辑的工作最终是做标记。之前和之后的一切都是你的申请。
在所有这些项目中,替代方案都是开发人员每次有人想做修改时手动编辑模板。
让客户在你的产品内按照自己的套餐设计自己的事务邮件和生命周期邮件,无需客服工单。
让销售和成功团队能够自行塑造客户沟通,利用CRM已经展示的字段和合并标签。
一次性构建可重复使用的模板,并从每个自动化工作流程中引用,而不是每个活动步骤重复标记。
把写一期作为设计任务而非HTML任务,让每本出版物保持自己的样式。
从已经知道如何呈现产品、价格和行动号召的模块中,汇集促销邮件和订单相关邮件。
让非技术团队在内部管理面板拥有邮件内容,而开发人员则保留组件和保护栏。
它是编辑的基础,而不是最终成品。这正是重点:下面的内容是你构建的钩子,而不是你默认的功能。
一个完整的编辑画布,包含选择、组件树和样式管理器——这些部分写起来最花时间,也最难做到完美。
定义组件类型,赋予它们自己的特征和标记,让编辑器理解你的应用程序已有的对象。
把你自己的方块注册到你自己的类别下,它们会像内置的方块面板一样显示在方块面板中。
在编辑时配置用户可切换的设备宽度,并在不离开画布的情况下预览每个尺寸。
把存储管理器指向你自己的端点。加载和保存变成对你的 API 的普通请求。
邮件预设、块包、资产管理器和存储适配器已经存在了,所以你不需要自己实现每一层。
面板、按钮和命令都可以配置,你也可以直接用自己的React接口驱动无头实例。
这些软件包从npm安装并随你的捆绑包一起发售。运行时没有编辑器服务可调用,也没有按座位设置的编辑器账户。
GrapesJS 提供了可视化编辑层。你的 React 应用掌控用户、数据、存储和发布——这正是嵌入编辑器而不是把人送到别人编辑的全部理由。
你的React应用
你的后台
将编辑嵌入他人产品中则引发了另一套问题。
两条路径最终都到达同一地点。唯一真正的区别在于模块被允许评估的位置。
反应
Vite、CRA、Remix客户端路由
@grapesjs/react
已发布的包装组件
GrapesJS
剪辑画布
电子邮件预设
邮件安全的区块和样式
渲染组件。没有其他安排。
GrapesJS React 集成Next.js
页面或应用路由器
dynamic(..., { SSR: false)
那一行额外的话
React 组件
你的编辑器包装
GrapesJS
仅限浏览器
电子邮件预设
邮件安全的区块和样式
其他所有内容——API 路由、数据获取、认证——都没有变化。
GrapesJS Next.js积分苏维埃社会主义共和国边界,曾经
GrapesJS 在初始化时会访问窗口和文档,因此无法在服务器上进行评估。Next.js这意味着通过 next/dynamic 导入编辑器组件,并使用 ssr: false 并赋予其加载骨架。这就是全部Next.js特定成本;编辑器周围的页面仍然可以被服务器渲染,其数据仍可来自 getStaticProps、getServerSideProps 或服务器组件。
三个包和一个组件。之后的内容——存储、自定义块、MJML——会在页面后面详细介绍。
npm install grapesjs @grapesjs/react grapesjs-preset-newsletterimport GjsEditor from '@grapesjs/react';
import newsletter from 'grapesjs-preset-newsletter';
import 'grapesjs/dist/css/grapes.min.css';
// A normal React component. The editor is a child of your tree, so your
// router, your auth context and your providers all still wrap it.
export default function EmailBuilder({ template, onSave }) {
return (
<GjsEditor
options={{
height: '100vh',
// Storage is wired to your own API further down this page.
storageManager: false,
plugins: [newsletter],
projectData: template,
}}
onEditor={(editor) => {
// Everything the user builds comes back out as plain data you can
// put straight into React state or POST to your backend.
editor.on('update', () => {
onSave({
html: editor.getHtml(),
css: editor.getCss(),
project: editor.getProjectData(),
});
});
}}
/>
);
}在Next.js中,一次动态导入可以让编辑器不进入服务器渲染:
// app/emails/page.tsx (or pages/emails.tsx)
import dynamic from 'next/dynamic';
// GrapesJS reaches for window/document as it initialises, so it can only run
// in the browser. In Next.js that means one dynamic import with ssr: false —
// this is the whole of the Next.js-specific work.
const EmailBuilder = dynamic(() => import('@/components/EmailBuilder'), {
ssr: false,
loading: () => <EditorSkeleton />,
});
export default function EmailsPage({ template }) {
return <EmailBuilder template={template} onSave={saveTemplate} />;
}上述版本与2026-09-03上已发布的封装进行了核对:grapesjs 0.23.6 是 BSD-3-Clause;@grapesjs/react 是 MIT。
这些来自编辑器核心及其邮件预设,而不是你必须写的内容。
用户在邮件中移动部分,并从块面板中新增部分。
文本、图片和按钮会被编辑到原位,内联编辑器可以切换到你已经授权的版本。
行、列和分段,都是由表格标记邮件客户端构建的,而非现代布局的CSS。
编辑时切换配置的设备宽度,这样布局在发送前可以仔细检查。
组件类型由你定义,它们有自己的特征和渲染标记。
一个由用户组装的现成板块组成,按你命名的类别分组。
一个用于图片的资产管理器,插件可以指向你自己的存储或你已经使用的媒体服务。
有命令历史,所以设计实验不是单向门。
MJML 的存在是为了让响应式邮件标记可以手工编写。在它上面加上可视化构建器,意味着没人需要手动编写。GrapesJS 的核心不包含 MJML——一个插件会在编辑器中添加 MJML 组件,使项目序列化为 MJML,而不是普通 HTML。
编译发生的地方
// pages/api/email/compile.ts
//
// mjml is a Node package — it parses and renders on the server, not in the
// browser. So the editor produces MJML in the client and this route turns it
// into the table-based HTML that email clients actually accept.
import mjml2html from 'mjml';
export default function handler(req, res) {
const { html, errors } = mjml2html(req.body.mjml, {
validationLevel: 'soft',
keepComments: false,
});
// MJML reports what it could not understand rather than failing silently.
if (errors.length) console.warn('[mjml]', errors);
res.status(200).json({ html });
}编译器是一个 Node 包,所以编译工作应该在服务器端进行——Next.js,是普通的 API 路由。反向则不对称:任意的 HTML 无法干净地转换回 MJML,所以在构建之前,先选择你的工作流程格式。
编辑器会给你的代码三个不同的东西,而React应用通常在不同时间点需要这三种。
editor.getHtml() + getCss()
当邮件预设处于激活状态时,渲染的邮件是基于表格和内联样式的。这就是你传递给发送服务商的内容。
配合MJML插件
源文档,如果你的工作流程是围绕MJML构建的。在服务器上编译它,得到你实际发送的HTML。
editor.getProjectData()
可编辑项目。存储它,方便用户几个月后重新打开模板,模板会和他们离开时完全一样。
渲染标记和可编辑项目是不同的产物,寿命不同。存储JSON;重新生成HTML。
这时嵌入式构建器领先于通用邮件工具:这些块可以知道你的域名。块不是产品卡的图片——它可以查找产品。
你的申请
电子邮件生成器
具体来说:任意的React组件不会被转换成邮件组件。JSX渲染的是DOM树,邮件客户端不会执行大部分内容。你写的是一个GrapesJS组件类型,其toHTML会输出邮件安全的标记,其特征映射到你应用拥有的记录上。线路是你的;编辑器会给出放置的位置。
通过发送产品实际发送的部分来减少重复设计工作,而不是用户每次都必须适应的通用版块。
标志、字标和前言文字,锁定品牌指南指定的布局。
邮件存在的唯一一条信息,尺寸适合在狭窄的视口中保存。
主力部分:一个带有段落的视觉图。
一个连接到你的目录的域块,而不是某个占位符,别人自己填补。
这些是根据你的账单数据渲染的层级和数据,所以价格变动不是模板编辑。
一个可重复的点列表,用表格排列,以便在Outlook中存活。
一个防弹按钮,带有每个客户端所需的缓冲和备份。
地址、偏好和取消订阅——合规关心的部分,不在用户手中。
模板只是保存的项目文档,所以发布入门库意味着做种行,并在用户选择时加载为 projectData。以下是大多数产品最终需要的类别:
常见起点
这些是布局类别,不是出售产品。GJS.Market 列出了电子邮件预设、块包和模板管理器——它不销售现成的电子邮件设计,本页面也不会显示不存在产品的卡片。
用户在编辑时切换设备宽度,画布会重新布局到该宽度。电子邮件宽度比网页宽度窄:600px多年来一直是安全的桌面最大宽度。
用户可以根据宽度更改哪些内容
预览就是预览。它显示的是标记如何重排,而不是特定客户端如何渲染——这是下一部分。
电子邮件客户端实现HTML和CSS的方式不同,且已有二十年历史。可视化构建器标准化了创作工作流程;它并不要求客户端彼此达成一致。
在多个上下文中剥离文档头,因此必须保留的样式必须是内联的。
在某些版本中,Windows通过Word渲染,这也是邮件标记仍然是基于表格的原因。
四种中最宽松的,因此作为你唯一的测试最没用。
它对媒体咨询和课程的处理;值得检查一下它是否对你的受众有意义。
这也是为什么这个页面不会告诉你它在所有地方都能完美运行。基于表格的输出带有内联样式是最可预测的起点,生产邮件仍应在你收件人实际使用的客户端中进行测试。
把编辑器连接到你已有的后端和数据模型。你的用户、认证、数据库、权限和发布流程都保持原位。
往返
// The editor asks your API for a template and hands it back on save.
// Your users, your auth, your database, your permissions — unchanged.
const options = {
storageManager: {
type: 'remote',
autosave: true,
stepsBeforeSave: 5,
options: {
remote: {
urlStore: `/api/email-templates/${templateId}`,
urlLoad: `/api/email-templates/${templateId}`,
// Your existing session cookie is all the auth it needs.
fetchOptions: { credentials: 'include' },
},
},
},
};
// pages/api/email-templates/[id].ts — an ordinary Next.js route handler.
export default async function handler(req, res) {
const session = await getSession(req);
if (!session) return res.status(401).end();
if (req.method === 'POST') {
await db.emailTemplate.update({
where: { id: req.query.id, orgId: session.orgId },
data: { project: req.body },
});
return res.status(200).json({ ok: true });
}
const row = await db.emailTemplate.findFirst({
where: { id: req.query.id, orgId: session.orgId },
});
return res.status(200).json(row?.project ?? {});
}GJS.Market 不托管你的模板、存储你的数据或发送你的邮件。它卖的是你自己运行的编辑器插件。
自定义编辑体验,直到它能作为你React应用的原生部分读取,而不是附加在里面的第三方面板。根本不需要去除厂商品牌标识。
用户所看到的内容
你能改变的
最彻底的方法是无头运行编辑器,自己用React构建整个界面,只用编辑器来处理画布和模型。
这是合理的考虑,直到部分清单写下来。以下每一项都是邮件编辑在可用前必须准备的——不是随便可有的。
电子邮件编辑的本质
所有东西都自己动手
上方每一排
从GrapesJS开始
编辑基础
打造你的邮件产品——而不是从零再造一个编辑器。我们不会给出"节省几个月"这样的数字:你的团队要花多久,取决于你的团队。
下面的每个商品都是真实产品,拥有活跃页面,名称、价格和缩略图均直接取自目录——因此页面上的任何内容都不会与实际销售内容不同步。
四种组合映射到真实需求。每个列表都是真实存在的——没有虚构插件填补图中的空白。
第一版:可视化编辑,邮件安全区块,HTML输出。
当你的工作流程围绕MJML构建并在服务器端编译时,
面向客户,在自己的基础设施中提供模板和资源。
SaaS页面构建器竞选卷:许多模板,许多图片,许多作者。
价格来自目录在组装时的版本。
你的客户打开建筑商
在你的应用里,在你的授权后面,在他们的套餐里有路由。没有第二个账户,没有第二个登录。
他们组装一个模板
从你定义的区块中,包括那些知道自己产品数据的区块。
它保存到你的数据库
项目文档会经过你的API路由,并落在属于他们组织的行中。
某个活动或工作流程会引用它
你的自动化通过ID选择模板——不需要知道编辑器的工作原理。
你的后端负责渲染和发送
合并字段在发送时解决,标记会交给你已经付费的供应商。
客户可以直观地控制邮件内容。你保留产品、数据和配送基础设施。
这种模式在其他毫无共同点的产品中反复出现。
可重复使用的客户沟通模板,由发送这些模板的团队拥有。
模板设计一次,并从自动化工作流程的每一步引用。
竞选创作作为视觉任务,每份出版物都保持自己的身份。
促销和订单相关邮件由已经熟悉目录的模块构建。
一个编辑,多个客户品牌,每个人看到的界面看起来像自己。
编辑负责创建邮件。你的基础设施发送邮件。保持这条线路清晰,使得整个架构更简单。
01赛段
用户负责编辑;编辑器将他们构建的内容序列化成项目文档。
项目 JSON第二赛段
它会将项目存储在拥有它的账户中,并在需要发送时渲染。
API 路由第03赛段
合并字段已解析,标记生成——如果你用MJML格式,可以从MJML编译。
HTML / MJML第四赛段
交给你已经使用的发送API,它有自己的交付能力和分析能力。
获奖者服务提供商团队交给的例子
标注是标注最终在哪里的示例,而不是内置集成。GrapesJS 和 GJS.Market 都没有为它们提供连接器;你从自己的后端调用他们的 SDK,就像你邮件的其他部分一样。
这是架构上的权衡,不是记分牌。右侧栏实说“视情况而定”:托管编辑之间存在差异,条款也会变更,我们不会替他们发明具体答案。
| 能力 | 自托管的GrapesJS | 托管邮件编辑器 |
|---|---|---|
| React 集成 | 是的——@grapesjs/react 封装 | 这取决于供应商 |
| 自托管 | 是的——你的捆绑包里有npm套餐 | 这取决于供应商和套餐 |
| 数据所有权 | 是的——你的数据库 | 这取决于供应商 |
| 自定义组件 | 是的——你自己的组件类型 | 这取决于供应商 |
| 自定义用户界面 | 是的——面板或无头实例 | 这取决于供应商 |
| 插件生态系统 | 是的——100+对GJS.Market | 这取决于供应商 |
| 你自己的后台 | 是的——你的 API 路由 | 这取决于供应商 |
| 核心许可 | BSD-3-Clause | 专有 |
| 供应商锁定 | 往下——项目数据归你所有 | 可能更高 |
GrapesJS栏目已与grapesjs 0.23.6和@grapesjs/react在2026-09-03上进行核对。欲与特定指定供应商及其公布价格进行对比,请参见专门页面。
获得帮助,围绕你的产品需求——组件、数据模型、存储和发送服务提供商——构建一个生产环境就绪的React邮件构建器。
构建一个自定义邮件生成器发送一份简报,描述你的堆栈、数据模型和所需输出格式,你就能收到一份明确范围的提案。
邻近页面会让同一个编辑器走不同的方向。
先从 GrapesJS 开始,集成到 React 应用中,然后用你的产品实际需要的邮件插件扩展编辑器。
安装包,挂载组件,并在你的应用中运行邮件编辑器。
快速入门预设、块包、存储适配器和资产集成——真实房源和实时价格。
浏览插件围绕你的组件、数据模型和发送服务提供商进行生产集成。
构建一个自定义邮件生成器