开发者电子邮件构建器

打造你自己的拖放式邮件编辑器,基于 GrapesJS

为你的SaaS、CMS、营销平台或内部工具创建一个可视化邮件编辑器。让用户通过拖拽模块构建响应式邮件,而你的团队则控制组件、模板、存储、输出和发布。

拖放式画布HTML、MJML 或项目 JSON你的数据库,你的ESP开源核心,BSD-3-Clause

你的用户通过可视化方式构建邮件。你的应用程序控制着体验。

实时编辑器

试试邮件生成器

这是本页上运行的真实 GrapesJS 编辑器——不是视频,也不是截图。从右侧拖入一个块,选中任意元素即可重新设置样式,切换到手机宽度,然后把生成的标记读出来。页眉和页脚是锁定的,与下面章节讲解的模式完全一致。

你能做的事

  1. 画布
  2. 样式
  3. 响应式
  4. 预览
  5. HTML / JSON
定义

什么是拖放式邮件生成器?

拖放邮件构建器是一种可视化编辑器,允许用户用可重复使用的组件创建邮件布局,而无需手动编写HTML表格和针对邮件的CSS。

区别在于谁必须知道规则。没有构建器,写邮件的人需要知道布局是嵌套表格完成的,大部分样式必须是内联的,且一个客户端的边距会压缩设计。有了构建器,规则只需你编码一次,分成块和组件,其他人只需整理。

没有视觉构建器

有人手写表格标记,然后手做检查。每封新邮件都是从上一封的副本开始的。

welcome.htmlhtml
<table role="presentation" cellpadding="0" cellspacing="0" width="600">
  <tr>
    <td style="padding:32px;font-family:Arial,sans-serif">
      <h1 style="margin:0 0 12px;font-size:26px">欢迎</h1>
      <p style="margin:0;font-size:15px;line-height:1.6">您的内容......</p>
    </td>
  </tr>
</table>

使用拖放式构建器

有人会安排块。表格标记是从你定义并审查过一次的组件生成的。

  1. 页眉
  2. Hero
  3. 正文
  4. 图片
  5. CTA
  6. 页脚

构建器不是为了让邮件变得简单。它负责让别人做出难的决定——你一次性做出的,在组件层面。

难点

为什么邮件生成器比网站生成器更难

网页运行在一个你大致可以理解的浏览器中。邮件运行在收件人打开的客户端中,而该客户端可能会重写你的标记、去除样式,或者用完全不同的引擎排版。因此,电子邮件构建器必须限制用户能产出的内容,而不仅仅是让生产过程愉快。

你的邮件必须存活的地方

  • Gmail

    网页版、安卓版和iOS版应用的行为各不相同,网页客户端会在渲染前处理你的样式。

  • Outlook

    桌面、网页和较新的Windows客户端实际上是不同的渲染器。Windows上的桌面构建历来是最严格的目标。

  • Apple Mail

    最宽松的常见客户端,这也让它成为一个糟糕的代理:一封看起来就在这里的邮件,可能在其他地方出错。

  • Yahoo Mail

    另一个有自己样式和标记净化规则的网页邮件客户端。

  • 移动客户端

    窄视口、激进的文本缩放,以及根据应用和操作系统版本不同的暗黑模式处理。

  • 其他一切

    企业网关、区域服务提供商以及那些从未出现在典型测试矩阵中的老旧客户端。

这对构建器提出了什么要求

  • 布局是表格,不是Flexbox或网格

    你的列、间隔和分隔符必须是表格组件。用户绝不应该能将裸 div 直接放入画布。

  • CSS 支持不稳定且不稳定

    将Style Manager限制在你实际测试过的属性上,而不是暴露浏览器的全部属性。

  • 样式在内排最安全

    要么用导出时内嵌的预设作者,要么在邮件离开后台前,在自己的流程里运行内嵌工具。

  • 媒体提问并非普遍被尊重

    设计时,单列备份已经是可接受的,并且将响应式规则视为改进而非必需。

  • 图片通常默认被屏蔽

    要求每个图片组件都加备用文本,并且绝不要让某个块依赖图片才能可读。

  • 暗色模式可能会重新给你的邮件颜色

    有些客户端会自动反转或调整颜色。避免设计依赖于特定背景保持该颜色的方案。

  • 网页字体经常无法加载

    在每个文本组件上都发布一个真正的备用栈,并且用备援而不是预期的面孔来检查邮件。

  • 脚本无法运行,交互性有限

    任何动态的东西都应该被链接支持。一个向用户提供交互式模块的构建器,实际上是在给他们提供无法正常工作的东西。

  • 商业邮件带有法律要求

    发送者身份和取消订阅机制是义务,而非设计选择。将它们锁定在模板中,而不是信任清单。

你不是在构建一个能产出漂亮HTML的编辑器。你是在打造一个无法产生危险HTML的编辑器。

客户端行为会随着发布和渲染模式变化,因此本页没有针对每个客户端的支持矩阵。验证你自己用户实际使用的客户端和功能。最后评测时间为2026-09-03。

编辑图层

为什么用GrapesJS作为邮件构建器?

GrapesJS 是一个开源(BSD-3-Clause)网页构建框架,目前是 0.23.6,GitHub 上大约有 26k+ 的星级。它给你编辑器中那些构建成本高且区分乏味的部分,同时为真正属于你产品的部分避开了。

画布与拖放

一个带有选择、拖拽目标、下放指示、调整大小和组件工具栏的 iframe 画布——那个需要几个月才能完善、没人会买你产品的交互层。

组件与区块

定义一个邮件安全的组件一次,然后将其暴露为用户拉入的阻挡。组件有自己的规则:接受什么、可编辑什么、样式化什么。

风格与特质经理

一个样式面板,你可以限制在邮箱实际支持的属性上,还有一个 traits 面板,用于设置非 CSS 的设置——链接目标、替代文本、合并字段。

图层与资源

一个用于嵌套表的结构树,这些表难以通过点击选择,还有一个你可以指向自己媒体库的资产管理器。

Storage Manager 与项目状态

整个编辑器的状态序列化成 project JSON。把 Storage Manager 指向你的 API,编辑器就不再在意数据在哪里了。

Commands 及插件

每个编辑器操作都是一个命名命令,你可以调用、覆盖或添加——这就是预设、导出器和GJS.Market上的100+插件如何扩展它而无需分支的方式。

GrapesJS 提供编辑层。你的应用程序提供电子邮件产品。

架构

拖放邮件构建器的工作原理

一条请求路径,从拖动块的人到打开邮件的人。下面的每个层都只有一个所有者,大多数集成问题都源于错误的责任。
  1. Your SaaS / application

    你的产品:账户、租户、账单,编辑者所挂载的路线。

  2. Email builder UI

    编辑器的外壳:模板选择器、保存状态、发送按钮、审批。

  3. GrapesJS

    视觉编辑引擎。它只知道组件和画布,却对你的用户一无所知。

  4. Editor modules

    你配置的编辑器子系统:哪些块存在,哪些块能接受,哪些可以样式,哪些可以编辑。

    • Blocks
    • Components
    • Styles
    • Traits
  5. Project JSON

    序列化编辑器状态。这是你存储的内容,以便邮件以后可以重新打开。

  6. Your backend / API

    你的API:权限、版本管理、合并标签解析、验证、活动记录。

  7. HTML / MJML

    你实际发送的标记。按需从存储的项目生成。

  8. Your email provider

    邮件投递服务商并报告邮件发生情况。

  9. Recipient

    收件箱,以及负责渲染它的客户端。

GrapesJS 从不与你的数据库或邮件提供商通信。它会给你一份文档;之后的一切都是你的架构。

职责

谁拥有什么

三位所有者,没有重叠。本页主题中最常见的架构错误是期望编辑在右侧栏做些什么。

你的应用
  • 用户与账户
  • 角色与权限
  • 模板记录
  • 存储与版本管理
  • 合并标签解析
  • 活动与排程
  • 输出验证
GrapesJS
  • 视觉画布
  • 拖放
  • 组件模型
  • 区块库
  • 样式编辑
  • 层树
  • 撤销/重做
  • 项目序列化
你的电子邮件服务提供商
  • 交付
  • 退信与投诉
  • 开启、点击与活动

右侧两列并不是 GrapesJS 的缺失——这些事情从来就不是编辑器的职责。从第一个迭代开始就把它们当作应用层的工作,集成才能保持简单。

输出

HTML、MJML 和 JSON:有什么区别?

有三个工件来自同一个画布,它们不能互换。一个是你保留的项目,另一个是你从中生成的交付格式。

项目 JSON

GrapesJS 核心

电子邮件的可编辑表示——组件、样式、资源和页面,完全符合编辑者持有的状态。

最适合

  • 保存正在进行中的作品
  • 重新打开编辑模板
  • 复制与版本管理
  • 不同版本之间的变化差异

你是怎么得到的

editor.getProjectData()

这是要存储的。只存储渲染的HTML意味着下一次编辑是从解析标记开始,而不是从用户构建的文档开始。

HTML

grapesjs-preset-newsletter

基于表格的标记,你交给发送服务商,样式内嵌,以便更多客户端保留。

最适合

  • 最后一封发出的邮件
  • 交付给现有管道
  • 对输出的最大控制

你是怎么得到的

editor.runCommand('gjs-get-inlined-html')

内联命令来自新闻通讯预设,而不是 GrapesJS 核心。没有它,你会得到画布标记和样式表,这不是你想发送的。

MJML

grapesjs-mjml

一种更高级的电子邮件标记语言,可编译为响应式表 HTML。

最适合

  • 以更少标记的响应式邮件作者
  • 保持存储源的可读性
  • 发送时编译为HTML

你是怎么得到的

editor.runCommand('mjml-code')

MJML 是一个独立的生态系统:编辑器插件渲染 MJML 组件,编译器将它们转换成 HTML。这两个都是第三方包,你会添加。

JSON 是项目。HTML 和 MJML 是交付。存储第一个,生成其他。

从画布到收件箱

  1. 可视化编辑器
  2. 项目 JSON
  3. 你的数据库
  4. 发送时渲染
  5. HTML
  6. 你的邮件服务商
发送时渲染而不是保存时渲染,是合并标签能按收件人解析的原因——也让你可以在每个模板上固定页脚而无需重新保存。
组件

为用户提供邮件安全的组件

不要给用户一张空白画布和一个 div。先发布一小组组件,这些组件已经编码了表格标记、内联样式和备用,然后让用户自行排列。这十个组件涵盖了大部分营销和生命周期邮件的实际需求。

  • 页眉

    标志、品牌条、前置标题文字。通常会被锁定,所以每封邮件都保持相同的身份。

  • Hero

    标题、辅助行和一个动作。大小使消息在不加载图像的情况下依然存在。

  • 正文

    一个带有真实字体备用堆栈和行高的段落块,能在手机宽度下保持。

  • 图片

    固定宽度、明确尺寸和必填替代文本,所以被屏蔽的图片仍然能保持邮件可读。

  • 按钮

    基于表格的按钮而非样式锚点——区别在更严格的客户端中可见。

  • 双列段

    一个表格行,在窄视口下自动堆叠,堆叠顺序由你预先决定。

  • 产品卡

    图片、名称、价格和链接,由后台填充的字段驱动,而不是复制粘贴。

  • 社交关系

    一排固定的图标和网址,可以通过设置编辑,而不是标记。

  • 分隔线

    用表格边框而不是 <hr> 元素画出的分隔线——多个邮件客户端会重新渲染 <hr>。

  • 页脚

    发送者身份、地址和退订链接。通常是锁定的,因为这些是义务。

让用户在不要求他们理解 HTML 邮件的情况下进行视觉设计。

从可重复使用的模块构建邮件

组件是定义;块是用户将组件放到画布上的方式。块库是你控制人们能构建什么的最有力杠杆——也是最容易因慷慨而出错的杠杆。

用户重复的循环

  1. 区块库
  2. 拖拽到画布
  3. 自定义
  4. 保存为模板

一幅无拘无束的画布

所有可用元素,每种风格都可以编辑,对结构没有意见。

  • 用户产生无人审核的标记
  • 关于某客户端渲染的支持请求
  • 模板在几周内就会偏离品牌
  • 没有安全的方式可以以后更改共享部分

一个策划的块库

一份你设计、测试过并可在中心更换的区块简短列表。

  • 输出会保持在你验证过的标记范围内
  • 新用户无需培训也能高效
  • 品牌规则存在于组件中,而非文档中
  • 改进一个模块会改善每封使用该模块的邮件
结构

模板、块和组件

三个层级,而这正是邮件构建器难以成长的原因。组件就是物品,块是添加方式,模板是完成的起点。

  1. 模板
  2. 组件
  3. 一个团队可以发展的模板系统

模板

完整的电子邮件设计

用户可以从一整封邮件开始——通讯、收据、入职步骤。作为项目JSON存储,使用时克隆。

可重复使用的部分

模板的可拖动单元包括:hero、条目行、CTA条带、页脚。

组件

领域特定元素

这些可编辑的原语放在一个区块里,拥有自己的traits和规则——一张知道价格的产品卡。

先构建组件,然后是暴露组件的模块,最后是排列组件的模板。从模板层面开始的团队最终会得到几十个几乎相同的设计,且无法更改。

扩展版通讯模板

通讯模板

  • ├── 页眉(锁定)
  • ├── Hero
  • ├── 文章块×3
  • ├── CTA
  • └── 页脚(锁定)

每个子块是一个模块;每个模块由组件组成。只需更改一次文章模块,每个基于该模板构建的通讯下一次打开时都会接收该模块。

护栏

给予用户自由,同时不让他们破坏模板

GrapesJS 中的锁定不是一个模式或计划层级——它是组件定义上的一组选项。锁定区域仍然会渲染、导出,并且在编辑器中拒绝拖拽、删除或重新样式。

公司页眉

锁定

每封邮件都要出现,每封邮件都一样。没人需要移动它。

可编辑内容

可编辑

发送者实际上是来写的文字和图片。

行动号召

可编辑

可编辑标签和链接,还有一份简短的颜色列表——不是下面的标记。

法律页脚

锁定

发送者身份和退订链接。这是义务,不是设计决策。

产生这种变化的选项

公司页眉
removable: false, draggable: false
可编辑内容
editable: true
行动号召
stylable: ['background-color', 'color']
法律页脚
removable: false, copyable: false

这能给你带来什么

  • 品牌安全编辑,无需每次发送审核步骤
  • 合规内容不会被意外删除
  • 一个更短的Style Manager,也是更简单的UI
  • 在每个模板中行为相同的批准块
  • 共享部分的中心修改,但不涉及草稿
参见受控无代码模式

这些选项控制编辑器UI。它们不是授权。直接发布到你的存档端点的修改项目仅受服务器验证的约束——所以每次都要验证后端的结构、所需区域和允许字段。

个性化

构建动态邮件内容

个性化邮件有两个独立的问题:让用户在不知道语法的情况下放置占位符,以及在发送时用真实数据解决占位符。编辑器解决了第一个问题。只有你的应用程序能解决第二个问题。

模板中的标签合并

  • {{first_name}}
  • {{company_name}}
  • {{order.total}}
  • {{unsubscribe_url}}

对编辑来说,这些只是普通文本。它们被完全按原文存储,保存、重新打开和导出时都未受影响。

用户如何插入

在你的文本组件中,将可用字段作为特征暴露——比如“名字”、“公司”、“订单总额”的下拉菜单——然后自己把令牌写入内容中。用户选择一个字段;他们永远不会学习语法,也不能创造渲染器不知道的标签。

动态块

块可以作为尚未存在内容的占位符。用户输入产品卡并配置显示哪些产品;这些值在邮件渲染时到达。

  1. 1用户放置产品卡
  2. 2你的后台在发送时查询目录
  3. 3姓名、价格、图片和网址均已填写
  4. 4渲染出来的HTML会送到你的供应商手中

GrapesJS 提供编辑体验。你的后台在邮件渲染或发送时解析动态数据和合并标签。

预览

发送前预览邮件

两种宽度几乎涵盖了设计审查的全部内容:邮件写作的宽度和手机宽度。两者在编辑器中只需切换设备即可,且都不等同于测试。

桌面600px创作宽度。几乎所有邮件模板都是600像素构建的。
手机375px大多数邮件实际上都被打开的地方。检查堆叠订单和抽签目标。

真正发现问题的工作流程

  1. 1编辑器预览切换设备,关闭图片,然后用备用字体阅读邮件。这能在几秒钟内发现结构和层级问题。
  2. 2检查输出阅读生成的标记,查找任何不该存在的内容——比如杂乱类、未内联规则、缺失的替代属性。
  3. 3发送到种子列表真实的客户端账户。这是唯一能显示收件人所见内容的步骤。
  4. 4如果它值得,就添加一个服务第三方服务会同时截图多个客户端的模板。当模板发放频率足够高,以至于种子列表成为瓶颈时,这样做是值得的。

编辑器内预览是浏览器渲染画布标记。邮件客户端通过自身引擎渲染该标记的转换版本,两者可能有所不同。预览用于设计审查;种子列表或渲染服务用于兼容性。

验证

发送前请先验证

大多数邮件灾难并不是渲染bug。它们是链接断裂、合并标签未填或取消订阅缺失。这三种情况在服务器上发现成本低,收件箱发现成本高。

内容

邮件完整了吗?

在模板还没能退出草稿之前就跑。

  • 主题行和标题已存在
  • 每张图片都有替代文本
  • 每个图片的URL都是绝对且可公开访问的
  • 模板中没有剩余占位副本
  • 项目中所需的区域仍然存在
链接

所有链接都能解析吗?

自动化成本低,且是最常见的单次故障。

  • 每个href都是绝对的,并且会返回成功状态
  • 没有mailto或tel的错别字
  • 跟踪参数的应用一致
  • 每个合并标签都匹配渲染器已知的字段
  • 渲染输出中没有任何标签未解决
合规

发送合法吗?

不可协商,所以要用代码而非清单来执行。

  • 取消订阅链接已存在且功能正常
  • 发送者身份和邮寄地址存在
  • 本次发送时,收件人的同意已记录
  • 已保存项目中锁定的合法页脚依然完整
  • 如果输出有任何部分来自用户输入,则会被净化
持久性

保存和恢复电子邮件项目

Storage Manager 是一个接口,不是数据库。在你自己的 API 上实现它,编辑器会通过你控制的端点加载、自动保存和恢复——这正是草稿、版本和批准成为可能的节点。

后端定义的生命周期

  1. 编辑
  2. 自动保存
  3. 草稿
  4. 版本
  5. 批准了
  6. 发表
storage-adapter.tsJS
// The editor hands you project JSON; your backend decides
// what a draft, a version and an approved template mean.
editor.Storage.add('email-api', {
  async load({ templateId }) {
    const res = await fetch(`/api/email-templates/${templateId}`);
    return res.json();               // -> project JSON
  },
  async store(data, { templateId }) {
    await fetch(`/api/email-templates/${templateId}`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      // Authorization is enforced server-side. Never trust this call.
      body: JSON.stringify({ project: data }),
    });
  },
});

自动保存是根据变更次数而非定时器限制的,因此一次编辑突发仍需一次请求。保持版本为JSON项目的不可变副本——恢复修订后只需加载,错误编辑不再是事件。

交付

连接您现有的电子邮件基础设施

这个架构没有要求你更改发送邮件的方式。编辑器生成文档;你的后端渲染文档并交给你已经付费的供应商。

  1. 01

    GrapesJS

    负责项目,并应要求进行加注。对接收者一无所知。

  2. 02

    HTML / MJML

    按需从存储的项目生成,样式内嵌或编译MJML。

  3. 03

    你的后台

    解析合并标签,验证输出,记录活动,调用提供者。

  4. 04

    你的邮件服务商

    负责送信、报告退信、投诉、打开邮件并点击回来。

后端发布的示例

  • Mailgun
  • Postmark
  • SendGrid

按字母顺序列出,作为上一跳的示例。任何拥有HTTP API或SMTP端点的提供者都符合相同形状,且互换不会触及编辑器。

GrapesJS 是编辑器,不是你的邮件投递服务。

GrapesJS 和 GJS.Market 均未与上述任何供应商集成,也不意味着有合作关系。交付能力、认证和抑制处理仍由您的服务提供商和应用负责。

send-campaign.tsts
// Server side. GrapesJS is not in this file — and that is the point.
const template = await db.emailTemplates.find(templateId);

// 1. Your application resolves merge tags. The editor never does.
const html = renderMergeTags(template.html, {
  first_name: user.firstName,
  unsubscribe_url: unsubscribeUrlFor(user),
});

// 2. Your ESP delivers it. Swap the client, keep the editor.
await esp.send({ to: user.email, subject: template.subject, html });
自建与采用

你应该从零开始构建一个电子邮件编辑器吗?

这不是判断,而是范围检查。每一行都是邮件生成器需要的。左列是你自己拥有的工作;右列是GrapesJS在你写组件前给你的。

能力从零开始使用 GrapesJS
视觉画布自己实现可得
拖放自己实现可得
组件模型自己实现可得
区块库自己实现可扩展性
样式编辑自己实现可得
层树自己实现可得
撤销/重做自己实现可得
资产管理自己实现可得
存储集成自己实现可配置
自定义组件自己实现支持
插件架构自己实现支持

“可用”意味着该能力随核心一同发布,只需配置,而不必从零构建。但这并不意味着不需要工作:任何认真的邮件构建器都要定义自己的组件、限制自己的样式,并编写自己的存储适配器。已于 2026-09-03 针对 grapesjs 0.23.6 验证。

打造你的电子邮件产品,而不是另一个编辑引擎。

市场

用插件扩展你的邮件构建器

GJS.Market目录中的真实商品,按所属组装阶段分组。名称、价格和图片直接来自市场,所以你看到的就是今天实际出售的商品。

发送邮件

导出完成的文档以便交接、审核或提交现有的构建流程。

浏览该类别

本页部分功能背后没有插件,本节也不会发明插件:目录中没有预览或垃圾邮件检查产品、CSS内联产品、合并标签产品以及现成的邮件模板产品。这些在这里被描述为可实施的模式,或是我们团队可以与你合作的工作。

技术栈

构建你的邮件构建工具栈

四个构建,仅从现有的商品列表中组装而成。从你要发货的那一行开始,等它有位置时再添加下一层。

价格来自构建时的实时目录。免费列表会被标记;付费列表直接链接到他们的产品页面。

快速入门

只需5步即可构建一个拖放式邮件构建器

作品的形状,以及正确的顺序。每个步骤都链接到正确覆盖的指南——本页是地图,不是教程。

  1. 1

    初始化编辑器

    先把GrapesJS挂载在容器上,设置两个设备对邮件的需求,然后先关闭默认的本地存储。

    GrapesJS 设置指南
  2. 2

    定义电子邮件组件

    写出基于表格的邮件组件,限制样式,并以块形式展示每个组件。

    电子邮件组件深入解析
  3. 3

    添加模板

    给用户一个起点。将模板存储为项目JSON,使用时克隆模板,而不是编辑原始模板。

    模板系统
  4. 4

    存储项目

    针对你的API实现存储适配器,这样草稿、autosave及其版本由你自己定义。

    存储插件
  5. 5

    渲染与发送

    发送时生成标记,服务器端解析合并标签,然后把结果交给你的提供商。

    寻求搭建帮助
email-editor.tsts
import grapesjs from 'grapesjs';
import newsletter from 'grapesjs-preset-newsletter';

const editor = grapesjs.init({
  container: '#email-editor',
  height: '100%',
  // Email is authored at a fixed width; give users one extra viewport
  // to check, not a full responsive breakpoint set.
  deviceManager: {
    devices: [
      { id: 'desktop', name: 'Desktop', width: '' },
      { id: 'mobile', name: 'Mobile', width: '375px' },
    ],
  },
  // Curated blocks only: the preset's table sections, plus your own.
  plugins: [
    (ed) => newsletter(ed, { inlineCss: true, showBlocksOnLoad: true }),
  ],
  // Point the editor at your API rather than the browser's localStorage.
  storageManager: {
    type: 'remote',
    autosave: true,
    stepsBeforeSave: 10,
  },
});
email-button.tsts
// An email-safe button: users edit the label and the link,
// never the table markup that makes it render in Outlook.
editor.DomComponents.addType('email-button', {
  isComponent: (el) => el.dataset?.type === 'email-button',
  model: {
    defaults: {
      draggable: '[data-gjs-type="cell"], td',
      // Users may recolour it; they may not restyle it into a div.
      stylable: ['background-color', 'color', 'border-radius'],
      traits: [
        { name: 'href', label: 'Link' },
        { name: 'label', label: 'Button text' },
      ],
      components: `
        <table role="presentation" cellpadding="0" cellspacing="0">
          <tr><td><a href="#">Read the update</a></td></tr>
        </table>`,
    },
  },
});

两个采样都运行在grapesjs 0.23.6上。“grapesjs-preset-newsletter”和“grapesjs-mjml”是独立的BSD-3-Clause封装——核心不含邮件预设——所以安装与你上面选择的输出格式相符的格式即可。

上线前

生产清单

什么区别于一个可用的演示和一个可以交给客户的邮件生成器?这里的所有内容都是你的工作,不是编辑器的。

编辑器

编辑体验

用户能做什么、不能做什么。

  • 策划的块库,不是默认的
  • 带有限制样式的邮件安全组件
  • 两种设备宽度的响应式编辑
  • 从空状态获得的模板
  • 锁定的页眉、页脚和法定区域
数据

持久性

用户制作的任何东西都不应该丢失。

  • Project JSON 通过你自己的 API 延续
  • 自动保存被变更次数限制
  • 带恢复功能的不可变版本历史
  • 覆盖模板存储的备份
  • 一个经过验证的旧项目重启路径
输出

系统中会留下什么

每次都在服务器上验证。

  • HTML 或 MJML 输出在发送前已验证
  • 所有链接都已检查且绝对
  • 每个合并标签都可以解析
  • 每个图片网址都是公开和永久的
  • 用户提供的HTML消毒过
电子邮件

交付能力与法律

那些不关设计的部分。

  • 在你的受众使用的客户端上进行了测试
  • 是在手机上查的,而不仅仅是台式机
  • 每次发送都取消订阅
  • 页脚中的发件人身份和地址
  • 各司法管辖区的追踪和同意处理
安全性

邮件构建器最容易被攻破的地方

电子邮件构建器接受用户自创的标记并发送给第三方。这种组合比典型的CRUD功能更值得关注。

  • 风险

    信任编辑器施加的限制

    锁定区域、受限样式和隐藏块都存在于浏览器中。精心制作的请求可以发布任何它喜欢的项目。

    该怎么办

    验证服务器上已保存的项目:有需要的区域、允许列表中的组件类型、在范围内的字段。

  • 风险

    发送未经消毒的自定义代码

    代码嵌入组件是每个邮件构建器都会收到的功能请求,它是一个指向客户收件箱的注入面。

    该怎么办

    净化存储的标记,并在渲染时重新净化。限制代码组件的使用权限,并记录每次使用。

  • 风险

    接受任何上传的文件

    编辑上传的邮件最终会被放在与邮件存续时间相同的公开网址上。

    该怎么办

    在服务器上验证类型和大小,重新编码图像,并从不携带会话 Cookie 的域名中提供资源。

  • 风险

    导致发送端点保护不足

    渲染和发送是昂贵且不可逆的操作。它们通常比编辑器路线保护得不那么严格。

    该怎么办

    按模板和收件人列表授权,限制速率发送,并在发送给完整受众前要求第二次检查。

  • 风险

    针对范围内的合并标签解析

    宽松模板渲染器会乐意插值发送方本不该看到的字段。

    该怎么办

    根据该模板的显式允许列表解析,渲染失败于未知标签,而不是发出该标签。

性能

保持邮件生成器的快速运行

编辑器是你应用中一个重要的依赖。这些杠杆才是关键,按它们通常的收益顺序排列。

  • 懒散地加载编辑器

    只在编辑邮件的路由中导入,且只在浏览器中导入。编辑器的任何内容都不属于服务器渲染或主捆绑包。

  • 懒加载可选插件

    代码查看器、图像编辑器或 MJML 编译器可以在用户打开该面板时出现,而不是在初始值时。

  • 保持区块图书馆简短

    每个块在启动时都会解析标记,并在调色板中渲染一张卡片。策划的集合既快又安全。

  • 为 autosave 加防抖

    通过变更计数而非按键来限速,因此一次打字会生成一个请求,而不是三十个。

  • 保持项目数据精简

    通过URL引用资源。项目JSON中的Base64图片会让每次加载、保存和版本副本变得更重。

  • 留意自定义组件

    组件逻辑在每次更改时都运行,是导致画布在长邮件中显得迟缓的常见原因。

这里故意不引用任何数据:数字取决于你的块数、组件逻辑和用户硬件。在每次更改前后,在你自己的应用中测量编辑器路由。

如何决定

自托管邮件构建器与托管平台

既然架构已经清晰,取舍也就很容易说清楚了。托管构建器能更快地摆在客户面前;你自己拥有的构建器则是产品的一项功能,而不是产品的一个依赖。

托管邮件构建平台

一个由厂商操作的可嵌入编辑器,通过其API和UI集成。

你能得到什么

  • 供应商运营的基础设施
  • 数据的驻留和保留取决于提供者
  • UI 的定制因产品和计划而异
  • 定制组件因产品和方案而异
  • 品牌塑造取决于你所参加的计划
  • 通过供应商的API实现后端集成
  • 发送取决于平台的型号
  • 编辑器始终是你产品内部的外部工具

最快找到工作编辑的路线,路线图和定价由别人掌控。

与托管供应商进行比较

你自己的 GrapesJS 构建器

这是一个开源编辑层,你可以配置、扩展并部署,作为你自己应用的一部分。

你能得到什么

  • 基础设施是你的,无论你已经跑到哪里
  • 数据会根据你的政策保留在数据库中
  • UI就是你的UI,从面板到语言都一样
  • 自定义组件是普通的应用程序代码
  • 品牌塑造就是你的产品看起来什么样
  • 后端集成是你自己的架构
  • 发送邮件会保留在你已经使用的服务商那里
  • 编辑器是本地功能,不是嵌入式工具

前期工作更多,编辑会随着你的产品成长而非绕着产品成长。

开始构建

托管平台之间差异很大,这也是为什么左侧栏写“取决于提供商”,而不是一概而论。请查看具体供应商关于数据位置、保留、定制限制以及离开模板后处理情况的条款。

集成

使用邮件构建器配合你的应用堆栈

GrapesJS 渲染成一个普通的 DOM 元素,因此整合它取决于哪个生命周期钩子调用 init,哪个调用 destroy。你的框架驱动你的应用;GrapesJS 驱动可视化邮件编辑层。

先从GrapesJS教程开始
FAQ

拖放邮件生成器问题

什么是拖放式邮件生成器?

一个可视化编辑器,让人可以用可复用的组件——页眉、文本、图片、按钮、页脚——拼装邮件,而不必手写表格标记和内联 CSS。邮件 HTML 的规则只需在组件里编码一次,而不必让每个写邮件的人都去学。

我能用 GrapesJS 构建一个拖放式的邮件构建器吗?

是的。GrapesJS 提供画布、拖放、组件模型、块库、样式和特性面板、图层树、撤销/重做和项目序列化。你提供安全的邮件组件、模板、存储适配器和发送管道。

GrapesJS支持邮件编辑吗?

核心是一个通用的网页构建框架,不提供电子邮件预设。邮件支持来自插件:grapesjs-preset-newsletter 增加了基于表格的块、面向电子邮件的 Style Manager 和 CSS 内联导出命令,grapesjs-mjml 增加了 MJML 组件。这两者都是独立的 BSD-3-Clause 包。

我可以在 GrapesJS 中使用 MJML 吗?

是的,通过grapesjs-mjml插件。它通过 MJML 编译器的浏览器构建,实时渲染 MJML 组件在画布中。editor.runCommand('mjml-code')返回 MJML 源代码,mjml-code-to-html将其编译为 HTML。

我可以导出HTML邮件吗?

是的。editor.getHtml()返回canvas标记,通讯预设添加gjs-get-inlined-html,返回带有内联CSS的HTML——这正是你想发送的。如果你想把步骤留在服务器端,也可以在自己的后端管道内联。

我可以把邮件模板存储在我自己的数据库里吗?

是的,你应该这么做。Storage Manager 是一个接口:在你的 API 上实现 load 和 store,编辑器会将项目 JSON 持久化到你的数据库。除非你选择放置,否则不会将任何内容存储在第三方服务中。

我可以创建自定义邮件块吗?

是的。定义一个组件类型,包含表标记、traits 和你想要的样式限制,然后注册一个插入它的块。这是你控制用户能生成内容的主要杠杆,它就是普通的应用程序代码。

我可以锁定邮件模板的部分内容吗?

是的,包含组件选项如removable: false、draggable: false、copyable: false和受限的stylable列表。请记住,这些是管理编辑器UI的——你的服务器仍需验证已保存项目是否包含其必须包含的区域。

我可以使用合并标签和动态内容吗?

是的。编辑器把标签{{first_name}}当作普通文本来处理,保存它不动,所以你可以通过特征下拉菜单放置标签,而不是让用户学习语法。这些标签的解析和真实数据是在渲染时完成的——GrapesJS不做这件事。

我可以连接SendGrid、Mailgun还是Postmark吗?

你的后端可以像现在一样:生成HTML,解析合并标签,调用提供商的API。GrapesJS不在那个请求路径中,GrapesJS和GJS.Market都不与这些提供商提供集成。

GrapesJS 会发送邮件吗?

不。它只是一个编辑器。投递、退信、投诉、抑制名单和互动事件都归你的邮件服务商所有;活动记录和发送排程则属于你的应用。

我可以在 React 中使用这个构建器吗?

是的。把编辑器挂载在一个参考过的容器上,保持该容器不进入React的渲染路径,卸载时销毁实例。如果你喜欢组件而不是手动生命周期处理,有官方的React包装包。

我可以和Vue或Angular一起使用吗?

是的。GrapesJS 渲染成一个普通的 DOM 元素,所以集成就是从框架的挂载钩子调用 init,从拆解钩子调用 destroy。没有官方的 Vue 或 Angular 封装器,也不需要。

我可以给邮件生成器贴白标吗?

是的。面板、按钮、图标、样式表以及编辑器自身的界面字符串都可以配置,这样编辑器看起来和阅读起来就像你产品的一部分,而不是嵌入式第三方工具。

我应该从零开始做一个邮件编辑器吗?

只有当编辑引擎本身就是你的产品时才会这样。如果你卖的是电子邮件产品——模板、广告活动、个性化、交付——那么画布、拖放和组件模型都是无差异化的工作,采用现有引擎则会留出预算给客户实际注意到的部分。
服务

需要帮助构建你的电子邮件构建器吗?

如果你更愿意让它正常运行而不是研究它,我们的团队基于GrapesJS构建了电子邮件编辑服务——包括本页中没有插件支持的部分。

  • GrapesJS 集成到现有应用中
  • 自定义邮件安全组件
  • MJML 集成与编译
  • 策划块库
  • 存储适配器与版本历史
  • 模板系统与入门库
  • 合并标签与动态块
  • 白标编辑器 UI
  • 自定义插件
  • 发布与审批工作流程
咨询GrapesJS专家
开始

打造你的邮件构建器

为用户提供一种可视化的方式来创建邮件,而无需强迫开发团队从零开始构建邮件编辑器。

构建

用GrapesJS开始组装

告诉我们编辑需要做什么,并制定一个整合的具体计划。

开始构建
委托

让我们来帮你构建

组件、模板、存储和发布,都交付到你的栈上。

咨询GrapesJS专家

你的用户负责构建邮件。你的产品拥有整个体验。