交付页面,而不是工单
点这段文字,直接改写。
26k+
GitHub 星标
1.4M+
npm 月下载量
100+
GJS.Market 插件数
BSD-3-Clause
核心许可证
从左侧面板把区块拖进画布——或者先点区块,再点画布。直接在页面上改文字、调整间距与圆角,切换视口看布局如何自适应。这是交互的等比模型;真正的 GrapesJS 编辑器就在下一节。
区块
拖一个区块进来——或者先点区块,再点画布。
点这段文字,直接改写。
桌面三列,手机一列。
样式
主色
三个公开的 GrapesJS 构建版本,只在你点击时才加载——在此之前不会发出任何请求。
GrapesJS 官方演示:右侧区块面板、中间画布、样式管理器和图层树。这里看到的一切都在开源核心里。
将在 iframe 中加载第三方演示。点击前不会发起任何请求。
一个页面,从头到尾
六个随核心一起提供的子系统,而在用户眼里它们只是一个动作。
把区块和组件直接拖到画布上,放好之后还能重新排序。
在页面本身上修改内容和样式——字体、间距、颜色和背景,无需写样式表。
借助编辑器的设备管理器和断点,为不同屏幕尺寸调整布局。
区块只做一次,就能在多个页面复用;改一处,处处生效。
通过素材管理器管理图片和其他媒体,指向你现有的任意存储。
把编辑器接到你自己的发布流程上——GrapesJS 交给你 HTML 和 CSS,之后怎么做由你决定。
这里的每一项,都是你自己动手就得设计、实现并长期维护的子系统。
GrapesJS 是一个自托管的开源编辑器框架,而不是一款托管的建站产品。正是这个区别,让它能装进别人的应用里。
从一个开源的编辑器地基出发。核心以 BSD-3-Clause 发布,官方 React 封装以 MIT 发布——两者都允许商业使用,且没有授权费。
编辑器运行在你自己的基础设施里。你和用户之间没有编辑器厂商,除非你主动发送,否则数据不会离开你的技术栈。
创建自定义区块、组件类型、命令和面板。插件 API 与生态里那些插件所用的完全是同一套。
替换面板、重做外壳,或者干脆用你自己的界面来驱动编辑器。界面不是固定的——上面的演示就是证明。
存储管理器直接与你的接口对话。项目、页面、素材和用户都留在你的数据库里,由你的鉴权保护。
用 GJS.Market 和 npm 上的插件来扩展编辑器,不必每种能力都自己写一遍。
底层是同一个编辑器内核,每一次只是针对不同的活儿做了不同的配置。
想要它的理由各不相同,但底下都是同一个问题:创建页面不该每次都得叫上开发。
把页面创建做成产品功能,客户不必离开你的应用。
打造属于自己的可视化编辑体验,而不是转售别人的。
在你已有的内容模型之上,加一层可视化。
为客户搭建可复用的页面体系,让他们在项目间隙也能自己维护。
把那些如今压在工程团队身上的常规排版和文案改动清出队列。
从一个可扩展的编辑器内核起步,而不是从空白画布加一个拖拽库开始。
页面编辑器不是一个功能,而是十几个必须彼此自洽的子系统——并且要在产品不断长大的过程中一直保持自洽。
一个页面编辑器实际包含什么
画布、放置目标、选中态、样式面板、断点、素材库、多页状态、持久化、一个能扛住这一切的撤销栈、导出、发布——以及它们全部的长期维护。
可视化编辑器、拖放、区块、组件、样式管理器、素材、页面、存储 API 和插件系统都随核心提供。你要补的,是你产品独有的那部分。
去做你的产品——而不是又一个从零写起的页面编辑器。
哪一栏都不是白来的。差别在于哪部分工作是你的。
| 子系统 | 从零开始 | 使用 GrapesJS |
|---|---|---|
| 编辑器画布 | 自己设计并实现 | 核心自带 |
| 拖放 | 放置目标、指示器、嵌套规则 | 核心自带 |
| 区块 | 定义格式和面板界面 | 区块管理器,另有现成的区块插件 |
| 组件 | 自建组件模型和属性系统 | 组件类型,支持属性与自定义行为 |
| 样式管理器 | 自建可视化 CSS 编辑器 | 核心自带,分区可配置 |
| 响应式控制 | 断点状态要贯穿整个编辑器 | 设备管理器,可用插件扩展 |
| 素材 | 素材库、上传流程、选择器 | 素材管理器,指向你的存储 |
| 页面 | 多页状态与导航 | 页面管理器 |
| 存储 | 序列化格式与接口 | 存储管理器对接你的 API |
| 撤销 / 重做 | 覆盖每一次变更的命令栈 | 核心自带 |
| 导出 | 自己生成 HTML/CSS | getHtml() / getCss(),另有导出插件 |
| 发布 | 归你 | 归你——这是刻意的 |
| 编辑器维护 | 归你 | 与一个开源项目及其生态共同承担 |
发布之所以留在你这一栏,是刻意为之:它必须贴合你的域名、你的 CDN 和你的发布流程。
GrapesJS 是你应用里的一层,而不是一个你要把用户交出去的平台。用户、内容和发布决定权都留在你手里。
持久化
你的 API
数据
你的数据库
分发
你的发布
关于把编辑器挂进现有应用的具体做法——iframe、路由、鉴权交接——请看 可嵌入页面编辑器指南
编辑器的设备管理器会在断点之间切换画布,在某个设备下设置的样式也只在该宽度生效。
用户可以按断点调整的内容
让用户针对不同屏幕尺寸调整布局、间距、排版和显隐。至于页面在某台设备上最终如何呈现,仍取决于你交付的 HTML 和 CSS——编辑器控制的是规则,不是浏览器。
区块就是用户拖进来的起点。下面这些是大多数页面编辑器上线第一天就需要的板块类型——你可以基于区块管理器 API 自己实现,也可以装一个区块插件,直接得到完整面板。
标题、辅助文案和一个主要操作。
标志与导航,在小屏上收成菜单。
用于陈述卖点的分栏,含图标、标题和文案。
套餐卡片,其中一档突出显示为推荐。
引言,配署名和头像。
由素材管理器填充的图片网格。
居中的单一行动召唤。
表单接到你指定的任意接口。
链接分栏、法务文字和次级导航。
这些是区块类型,不是商品。真正在售的区块插件在本页更下方。
正是这个区别,决定了 GrapesJS 在你眼里是个建站玩具,还是一个可以拿来做产品的编辑器内核。
区块
面板里的一个条目。把它拖进画布会插入内容——区块本身并不会留在页面上。
组件
区块落地后变成的东西。组件有自己的类型和属性,也有关于能否嵌套、拖动或删除的规则。
自定义组件
注册你自己的组件类型,编辑器会把它当作一等公民:你的属性、你的工具栏、你的约束,背后是你的数据。
因为自定义组件背后是你自己的代码,GrapesJS 编辑器能编辑那些通用建站工具根本没有概念的东西——接上你套餐数据的价格表、读取你商品目录的商品网格、提交到你接口的表单。
大多数用户并不想要一张白纸。给他们一组起步版式,并允许保存自己的——预设配置的是整个编辑器,模板给的是一个可以直接改的页面。
用户通常会要的版式
这些是版式类别,不是商品条目——是你会为自己的用户准备或精选的东西。真正可以安装的预设和模板管理器在下方插件区。
存储管理器是你 API 的客户端,而不是一项服务。把它指向你的接口,编辑器就会通过它们读写。
数据的去向
const editor = grapesjs.init({
container: '#editor',
// Each page is a row in your database, behind your own auth.
storageManager: {
type: 'remote',
autosave: true,
options: {
remote: {
urlStore: `/api/pages/${pageId}`,
urlLoad: `/api/pages/${pageId}`,
fetchOptions: { credentials: 'include' },
},
},
},
});
// Publishing stays on your side — your domains, your CDN, your workflow.
async function publish() {
await fetch(`/api/pages/${pageId}/publish`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ html: editor.getHtml(), css: editor.getCss() }),
});
}把 GrapesJS 接到你自己的后端,由你决定项目、页面、素材和用户如何存储。GJS.Market 出售的是插件——它不托管你的数据。
用户搭建页面
在画布上拖放、编辑、调样式。自动保存让进行中的工作可以恢复。
通过你的 API 落库
存储管理器把项目提交到你的接口。此时还没有发布。
按访客看到的样子渲染
导出 HTML 和 CSS,在只有作者能访问的路由上渲染预览。
你的流程,你的规则
审批、定时、版本——你产品原本怎么做就怎么做。这一步没有 GrapesJS 的事。
从你的基础设施分发
你的域名、你的 CDN、你的缓存。页面就是普通的 HTML 和 CSS。
GrapesJS 负责编辑体验,你的应用掌控发布流程。
下面每一张卡片都是真实在售的条目——名称、价格和缩略图都实时来自商店,所以本页展示的内容不会和实际在售的东西对不上。
四套起步配置。每一套都是真实条目的组合,而不是打包商品——需要哪些装哪些,其余的略过。
面向必须带来转化的营销页
面向布局共享的多页网站
所见即所得编辑器面向产品内的页面创建
面向既有内容之上的可视化层
价格实时来自商店。
两个文件,编辑器就出现在屏幕上。之后的一切都是配置。
npm install grapesjsimport grapesjs from 'grapesjs';
import 'grapesjs/dist/css/grapes.min.css';
// The editor core. Mount it on any container in your app.
const editor = grapesjs.init({
container: '#editor',
});然后定义用户能拖什么,以及它落地后会变成什么:
// A block is what the user drags. A component is what it becomes
// on the canvas once dropped — and what your app can then control.
editor.BlockManager.add('pricing-table', {
label: 'Pricing',
category: 'Sections',
content: { type: 'pricing-table' },
});
editor.DomComponents.addType('pricing-table', {
model: {
defaults: {
// Lock the frame, let the user edit only what you allow.
draggable: 'main, section',
traits: ['plan', 'currency'],
},
},
});从这里往后的工作都与产品相关:给用户哪些区块、注册哪些组件类型、项目存在哪里。
核心与框架无关——它挂载在一个 DOM 容器上。下面这些页面分别介绍各自的接法。
只列出能对照各项目已发布的包和文档核实的特征。各家的能力差异源于设计目标不同——Craft.js 刻意不带界面,Puck 以 React 为先,Builder.io 是托管平台。
| 特征 | GrapesJS | Puck | Craft.js | Builder.io |
|---|---|---|---|---|
| 开源 | 是 —— BSD-3-Clause | 是 —— MIT | 是 —— MIT | SDK 为 MIT;平台闭源 |
| 自托管 | 是 | 是 | 是 | 托管服务 |
| 框架 | 与框架无关,另有 React 封装 | React | React | 多框架 SDK |
| 自定义区块 | 是 —— 区块管理器 | 是 —— 组件配置 | 是 —— 用户组件 | 是 —— 注册组件 |
| 自定义组件 | 是 —— 带属性的组件类型 | 是 —— 带字段的 React 组件 | 是 —— 带设置的 React 组件 | 是 —— 带输入项 |
| 自定义编辑器界面 | 是 —— 面板可替换,也可无界面驱动 | 自带界面,可换主题 | 自备界面 —— 不含 UI | 厂商界面 |
| 自有存储后端 | 是 —— 存储管理器对接你的 API | 是 —— 数据由你持久化 | 是 —— 状态由你持久化 | 内容存放在 Builder.io |
| 自有发布流程 | 是 | 是 | 是 | 通过 Builder.io 接口 |
| 插件生态 | 有 —— GJS.Market 与 npm | 成长中 | 较小 | 厂商集成 |
许可证已于 2026-09-03 对照 npm 仓库核实:grapesjs 0.23.6 以 BSD-3-Clause 发布;@measured/puck、@craftjs/core 和 @builder.io/react 均以 MIT 发布。能力项依据各项目的公开文档整理——决策前请自行复核。
同一个编辑器内核,问题不同。如果下面某一条更贴近你的情况,就从那里开始。
从 GrapesJS 起步,定制编辑体验,再用你产品需要的插件扩展它。
更多关于用 GrapesJS 构建编辑器的内容: