Principiante
El bucle central: poner un editor en pantalla y poner cosas en él.
PageKit: el creador de sitios GrapesJS autoalojado, con el código fuente incluido. Obtener acceso anticipado
Aprende GrapesJS paso a paso. Construye tu primer editor visual, añade bloques y componentes personalizados, configura estilos y recursos, guarda proyectos, exporta HTML/CSS, instala plugins e integra GrapesJS con React, Vue, Angular o Next.js.
El núcleo de GrapesJS se publica bajo la licencia BSD-3-Clause; el wrapper oficial de React @grapesjs/react es MIT. Ambos permiten uso comercial. Cada ejemplo de esta página se verificó con GrapesJS 0.23.6.
Al final de este tutorial, tendrás un editor visual funcional de arrastrar y soltar que puede crear páginas, editar componentes, gestionar estilos y recursos, guardar proyectos y exportar los HTML y CSS resultantes.
Ruta de aprendizaje estimada
Principiante → Intermedio → Producción
El tiempo que tarde depende enteramente de cuánto de la capa de producción necesite tu producto. Los pasos 1–6 son una tarde; los pasos 7–12 son el trabajo.
Abrir la demo oficial de GrapesJSMuy poco. Si sabes escribir una página a mano, puedes seguir esto.
Deberías reconocer una etiqueta, una clase y una propiedad CSS. GrapesJS edita HTML y CSS — nada más exótico.
Suficiente para leer un objeto literal y una función. Todos los ejemplos aquí son JavaScript puro.
Solo si instalas desde npm. La ruta de CDN en el paso 1 solo necesita un editor de texto y un navegador.
No necesitas experiencia previa en GrapesJS, ni un framework. React, Vue, Angular y Next.js se cubren en el paso 11, una vez que el núcleo esté claro.
Esta es la ruta a seguir si tienes algún tipo de paso de compilación. Instala el editor y su hoja de estilos en tu proyecto; nada se recupera de un host de terceros en tiempo de ejecución.
npm install grapesjsNo tienes ninguna herramienta de compilación: dos etiquetas en un archivo HTML y tienes un editor. Perfecto para una primera vista o un prototipo. Para cualquier cosa que envíes, pinea una versión exacta en lugar de seguir la última versión.
<link
rel="stylesheet"
href="https://unpkg.com/grapesjs/dist/css/grapes.min.css"
/>
<script src="https://unpkg.com/grapesjs"></script>
<div id="gjs"></div>
<script>
// The UMD build puts the library on window.grapesjs
const editor = grapesjs.init({ container: '#gjs' });
</script>El núcleo editorial
El lienzo, el árbol de componentes, arrastrar y soltar, deshacer/rehacer, los paneles y los gestores para bloques, estilos, recursos, traits, capas y almacenamiento.
Una hoja de estilo
grapesjs/dist/css/grapes.min.css — el propio Chrome del editor. Sin él tienes un editor funcional que parece roto.
Sin bloqueos
El núcleo incluye una paleta de bloques vacía. Los bloques de columna/texto/imagen familiares provienen de un plugin, que es el paso 3.
Sin backend
Sin cuentas, sin base de datos, sin alojamiento. GrapesJS se ejecuta en el navegador y entrega los datos a tu aplicación, que es el paso 7.
Es un componente del lado del cliente. Tu aplicación autentica al usuario, decide qué proyecto abrir, monta el editor en un elemento DOM y recibe los datos del proyecto cuando se guardan. Todo lo que esté por encima y por debajo del editor es tuyo.
<!-- The editor takes over this element completely.
Do not render anything inside it yourself. -->
<div id="gjs"></div>import grapesjs from 'grapesjs';
import 'grapesjs/dist/css/grapes.min.css';
const editor = grapesjs.init({
// Where the editor mounts: a selector or an HTMLElement.
container: '#gjs',
height: '100vh',
width: 'auto',
// Do not adopt the markup already inside #gjs...
fromElement: false,
// ...load this instead. Strings are parsed into components.
components: `
<section class="hero">
<h1>Hello GrapesJS</h1>
<p>Drag a block from the panel on the right.</p>
</section>`,
style: `
.hero { padding: 64px 32px; font-family: system-ui, sans-serif; }
.hero h1 { margin: 0 0 12px; font-size: 40px; }`,
// Storage is ON by default and writes to localStorage.
// Turn it off until you have decided where projects really live.
storageManager: false,
});Una interfaz de tres partes: el lienzo en el centro, el conmutador de paneles arriba a la derecha y — una vez que hayas añadido bloques en el paso 3 — una paleta desde la que arrastrar. El editor de arriba de esta sección es exactamente esta configuración con seis bloques y tres anchos de dispositivo añadidos.
Abrir la demo en vivoBloquear
Una entrada de paleta. Existe solo en el panel y contiene una receta de qué crear. Tiene una etiqueta, una categoría, un icono y contenido.
Componente
Un nodo en el lienzo. Tiene un tipo, atributos, estilos, hijos, y es lo que se exporta y guarda.
Un bloque es lo que el usuario arrastra al lienzo. Una vez soltado, crea componentes dentro del editor. Un bloque puede crear un subárbol completo de componentes — y el mismo bloque que se cae dos veces crea dos subárboles independientes.
// A Block is a palette entry. Dropping it creates Components.
editor.Blocks.add('hero-section', {
label: 'Hero',
category: 'Sections',
// Shown in the palette. Any HTML string works; an inline SVG keeps it sharp.
media: '<svg viewBox="0 0 24 24" width="22"><rect x="3" y="5" width="18" height="6" rx="1" fill="currentColor"/><rect x="3" y="13" width="11" height="3" rx="1" fill="currentColor" opacity=".5"/></svg>',
content: `
<section class="hero">
<h1>Headline</h1>
<p>Supporting copy.</p>
<a href="#" class="btn">Call to action</a>
</section>`,
});
// The same block, expressed as a component definition instead of HTML.
// Use this form once you have your own component types (step 10).
editor.Blocks.add('product-card', {
label: 'Product card',
category: 'Commerce',
content: { type: 'product-card' },
});Esto sorprende a casi todo el mundo. Un editor de GrapesJS ya de fábrica tiene una paleta vacía — el conocido conjunto de "1 columna / 2 columnas / texto / imagen" que aparece en cada captura de pantalla viene de grapesjs-blocks-basic o de uno de los presets. O escribes tus propios bloques, como antes, o añades un preset.
import grapesjs, { usePlugin } from 'grapesjs';
import blocksBasic from 'grapesjs-blocks-basic';
// The core ships no blocks at all. The familiar
// "1 column / 2 columns / text / image" palette is a plugin.
grapesjs.init({
container: '#gjs',
plugins: [usePlugin(blocksBasic, { flexGrid: true })],
});Un subárbol típico
// Every node in the canvas is a Component, and the canvas is a tree.
const wrapper = editor.getWrapper();
wrapper.components().forEach((component) => {
console.log(
component.get('type'), // 'text' | 'image' | 'link' | your own type
component.getName(), // label shown in the Layer manager
component.components().length // number of children
);
});
// React to what the user selects — the hook most custom UI hangs off.
editor.on('component:selected', (component) => {
console.log('selected', component.getId(), component.get('type'));
});// Traits are the settings panel for a component.
// By default a trait writes an HTML attribute.
editor.Components.addType('cta-button', {
extend: 'link',
model: {
defaults: {
name: 'CTA button',
attributes: { class: 'btn' },
components: 'Call to action',
traits: [
{ name: 'href', label: 'Link' },
{ name: 'title', label: 'Title' },
{
type: 'select',
name: 'target',
label: 'Opens in',
options: [
{ id: '', name: 'Same tab' },
{ id: '_blank', name: 'New tab' },
],
},
],
},
},
});grapesjs.init({
container: '#gjs',
styleManager: {
// Sectors are the collapsible groups in the right-hand panel.
// Listing them yourself is how you stop the editor offering
// 100+ CSS properties to a non-technical author.
sectors: [
{
id: 'typography',
name: 'Typography',
open: true,
properties: [
'font-family',
'font-size',
'font-weight',
'line-height',
'color',
'text-align',
],
},
{ id: 'spacing', name: 'Spacing', properties: ['margin', 'padding'] },
{
id: 'dimension',
name: 'Dimension',
properties: ['width', 'max-width', 'height'],
},
{
id: 'decorations',
name: 'Decorations',
properties: ['background-color', 'border-radius', 'border', 'box-shadow'],
},
],
},
});Estructura de componentes
Qué existe, qué contiene qué, qué puede añadirse o eliminarse. Controlado con el tipo de componente, droppable, draggable y removable.
Diseño de componentes
Cómo puede ser un componente. Controlado con la configuración Style Manager y con stylable / unstylable en el propio componente.
// Structure and styling are separate concerns. A component can accept
// children while refusing to be restyled beyond a fixed allowance.
editor.Components.addType('brand-heading', {
extend: 'text',
model: {
defaults: {
name: 'Brand heading',
// Only these properties reach the Style manager for this component.
stylable: ['color', 'text-align'],
// Everything else stays on the class in your own stylesheet.
attributes: { class: 'brand-h2' },
},
},
});grapesjs.init({
container: '#gjs',
assetManager: {
// Seed the panel with images you already host.
assets: [
'https://cdn.example.com/hero.jpg',
{ src: 'https://cdn.example.com/team.jpg', name: 'Team', category: 'People' },
],
// Your upload endpoint. Set `upload: false` to disable uploading entirely.
upload: 'https://api.example.com/uploads',
uploadName: 'files',
headers: { Authorization: 'Bearer <token>' },
multiUpload: true,
// Add the response's assets to the panel automatically. Your endpoint must
// answer with { data: [ ...assets ] }.
autoAdd: true,
},
});// Full control: upload wherever you like, then hand the URLs back.
grapesjs.init({
container: '#gjs',
assetManager: {
async uploadFile(event) {
const files = event.dataTransfer
? event.dataTransfer.files
: event.target.files;
const urls = await uploadToYourStorage(files); // S3, R2, Cloudinary…
editor.AssetManager.add(urls);
},
},
});
// Without `upload` or `uploadFile`, dropped images are embedded as base64
// straight into the project — convenient in a demo, painful in production.Sin ni subida ni uploadFile configurados, las incrustaciones GrapesJS dejaron imágenes en el proyecto como base64. Funciona al instante y infla el proyecto almacenado hasta que se vuelve lento de cargar y caro de mover. Conecta el Asset Manager a un almacenamiento real antes de que alguien empiece a producir contenido.
grapesjs.init({
container: '#gjs',
storageManager: {
type: 'remote',
autosave: true,
autoload: true,
// Batch changes: save after N edits rather than after every keystroke.
stepsBeforeSave: 5,
options: {
remote: {
urlLoad: '/api/projects/42',
urlStore: '/api/projects/42',
headers: { 'X-CSRF-Token': csrfToken },
credentials: 'include',
// Shape the request body to match your API…
onStore: (data) => ({ project: data }),
// …and pull the project back out of your response.
onLoad: (result) => result.project,
},
},
},
});// When `remote` does not fit — GraphQL, a queue, an offline-first cache —
// register a storage of your own and select it by name.
editor.Storage.add('my-api', {
async load() {
const res = await fetch('/api/projects/42');
const { project } = await res.json();
return project; // the object you previously stored
},
async store(data) {
await fetch('/api/projects/42', {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ project: data }),
});
},
});
// storageManager: { type: 'my-api' }
// You can also drive it by hand, with no storage configured at all:
const project = editor.getProjectData(); // plain JSON — store it anywhere
editor.loadProjectData(project); // and put it backGrapesJS proporciona el editor y la capa de datos del proyecto, pero tu aplicación decide dónde se almacenan los datos de producción. Qué usuario es propietario de un proyecto, a qué tenant pertenece, quién puede abrirlo, cuántas revisiones conservas, cuándo está respaldado — nada de eso está en la biblioteca, y nada debería estarlo.
const html = editor.getHtml();
const css = editor.getCss();
// Two things surprise everyone on their first export:
//
// 1. getHtml() returns the canvas wrapped in <body> … </body>.
// Strip or template around it before you save a fragment.
// 2. getCss() includes GrapesJS's own canvas reset unless you opt out:
const pageCss = editor.getCss({ avoidProtected: true });
// Export one branch instead of the whole page:
const selected = editor.getSelected();
const partial = editor.getHtml({ component: selected });
// The editable project — NOT the same thing as the exported page.
const project = editor.getProjectData();getHtml() se envuelve en <body>
El componente del envoltorio se exporta como un elemento del cuerpo. Si guardas un fragmento, la plantilla alrededor o lo desmontas — no asumas que recuperas una sección desnuda.
getCss() incluye el reinicio del editor
GrapesJS incluye una pequeña hoja de estilo protegida para el lienzo. Pasar avoidProtected: cierto cuando solo quieres el CSS que realmente creó tu lector.
Una cadena típica de publicación
getHtml() y getCss() te dan lo que ven los visitantes. getProjectData() te da lo que el autor puede seguir editando. Guarda el proyecto; regenera la página a partir de él. Almacenar solo HTML significa que la siguiente edición empieza con el marcado analizado en lugar del documento que el autor ha construido.
import grapesjs, { usePlugin } from 'grapesjs';
import blocksBasic from 'grapesjs-blocks-basic';
import forms from 'grapesjs-plugin-forms';
grapesjs.init({
container: '#gjs',
plugins: [
usePlugin(blocksBasic, { flexGrid: true }),
usePlugin(forms, {}),
],
});// A plugin is just a function that receives the editor.
// Anything you can do at init you can do inside one.
export default function dividerPlugin(editor, options = {}) {
const category = options.category ?? 'Basic';
editor.Blocks.add('divider', {
label: 'Divider',
category,
content: '<hr class="divider" />',
});
editor.Commands.add('clear-canvas', {
run: (ed) => ed.Components.clear(),
});
}
// Then: plugins: [usePlugin(dividerPlugin, { category: 'Layout' })]¿Necesitas funcionalidades que no estén incluidas en tu editor base? Explora los plugins y extensiones disponibles a través de GJS.Market. A continuación tienes listados reales del catálogo, agrupados por el paso al que pertenecen.
Listados reales del catálogo GJS.Market, agrupados por la parte del tutorial que extienden. Nada aquí reemplaza el núcleo — cada uno llena una junta que el núcleo deja deliberadamente abierta.
Paso 3 — una paleta desde la que empezar en lugar de escribir cada bloque a mano.
Explora la categoríaEl paso 3 de la paleta inicial dice que falta el núcleo: un puñado de bloques básicos, registrados para ti.
Un preset de página web — bloques, paneles y una configuración predeterminada sensata en un único plugin, en lugar de montarlos tú mismo.
Bootstrap 5 bloques de diseño, si tu producto ya se envía Bootstrap y el editor debería producir el mismo margo.
Una biblioteca de bloques Tailwind responsivos listos para equipos, para equipos cuyo sistema de diseño ya es de clases Tailwind.
Pasos 4 y 10 — tipos de componentes que alguien ya ha construido y probado.
Explora la categoríaUn tipo de componente tabulador, completo con su bloque — un ejemplo práctico de todo lo que cubre el paso 10.
Un bloque deslizante con control táctil construido sobre Swiper, uno de los componentes que casi todo creador de páginas acaba necesitando.
Componentes y bloques de formulario: entrada, área de texto, select, casilla de selección, radio y botón, cableados como tipos de componentes reales.
Un componente icono con un selector Iconify en modal — un buen modelo para un rasgo que abre UI personalizado.
Pasos 6 y 7 — un lugar donde los proyectos y las subidas puedan publicarse.
Explora la categoríaUn envoltorio de almacenamiento IndexedDB: el mismo contrato Storage Manager del paso 7, respaldado por la propia base de datos del navegador.
Un wrapper de almacenamiento Firestore, si prefieres apuntar el editor a una base de datos alojada en lugar de construir un endpoint de guardado.
Sustituye el uploader predeterminado por Cloudinary — el gancho uploadFile del paso 6, ya escrito.
Cambia el uploader de Asset Manager por Filestack, para los equipos que ya lo usan para el resto de sus subidas.
Pasos 8 y 9 — edición de texto más rica, edición de código y objetivos de exportación.
Explora la categoríaSustituye el editor de texto enriquecido integrado por CKEditor 5 en modo inline. CKEditor está licenciado por separado por su fabricante.
Edita el HTML y CSS del componente seleccionado directamente en el lienzo — útil mientras aún estás aprendiendo el árbol.
Empaqueta la exportación desde el paso 8 en un zip descargable, que es el proceso de publicación más rápido que existe.
Más acciones en el editor de texto enriquecido integrado, sin necesidad de tener que usar un editor completo de terceros.
Una tarjeta de producto, como tipo de componente
editor.Components.addType('product-card', {
// Lets GrapesJS recognise the type when parsing saved HTML.
isComponent: (el) => el.dataset?.gjsType === 'product-card',
model: {
defaults: {
name: 'Product card',
attributes: { 'data-gjs-type': 'product-card', class: 'product-card' },
// Author-visible settings. `changeProp` writes to the model
// instead of to an HTML attribute.
traits: [
{ name: 'sku', label: 'SKU', changeProp: true },
{
type: 'checkbox',
name: 'showPrice',
label: 'Show price',
changeProp: true,
},
],
sku: '',
showPrice: true,
// Fixed structure: the author edits the parts, not the layout.
components: [
{ type: 'image', attributes: { class: 'product-card__image' } },
{ type: 'text', name: 'Name', components: 'Product name' },
{ type: 'text', name: 'Price', attributes: { class: 'product-card__price' }, components: '$0.00' },
{ type: 'cta-button', components: 'Add to cart' },
],
// Locks that make the card a card and not a free-form div.
droppable: false,
stylable: ['background-color', 'border-radius', 'box-shadow'],
},
init() {
this.on('change:showPrice', this.togglePrice);
},
togglePrice() {
const price = this.components().at(2);
price?.addStyle({ display: this.get('showPrice') ? 'block' : 'none' });
},
},
});Una aplicación SaaS puede exponer componentes específicos de producto — una tabla de precios conectada a planes reales, una tarjeta de producto vinculada a un SKU, un widget de reserva — en lugar de un editor genérico y sin restricciones de HTML. Los autores tienen menos opciones y mejores resultados, y tu cola de soporte nunca ve una página rota por un flotador suelto.
Los pasos 3, 5 y 10 se combinan en lo más útil que puedes hacer con GrapesJS: reemplazar "todo es posible" por "estas siete cosas, hechas correctamente". Cada mecanismo es uno que ya has conocido.
Bloques personalizados
La paleta es el menú. Si no está en la estantería, nadie puede añadirlo.
Componentes personalizados
Estructura fija por bloque, con las partes que deberían ser editables marcadas como editables.
Rasgos
Los ajustes que recibe un autor — un encabezado, un enlace, una variante — en lugar de marcado en bruto.
Configuración Style Manager
Sectores que solo listan las propiedades que tu sistema realmente permite.
Estilos permitidos
stylable y unstylable por componente, así que una tarjeta puede cambiar de color pero no convertirse en un float.
Componentes reutilizables
Piezas compartidas que se mantienen sincronizadas en lugar de copiarse por página.
Plantillas
Un documento inicial por tipo de página, para que nadie empiece con un lienzo en blanco.
UI personalizado
Los paneles de GrapesJS son reemplazables. Un editor de producto rara vez se parece al predeterminado.
Tu sistema de diseño SaaS
Convierte GrapesJS de un editor genérico en uno diseñado específicamente para tu producto.
Dos guías van más allá en este tema, en dos direcciones:
GrapesJS se renderiza en un elemento DOM simple, así que "integrarlo con un framework" se reduce a una pregunta: qué gancho de ciclo de vida llama a init() y cuál llama a destroy(). El patrón que aparece a continuación es React; las guías dedicadas cubren el resto, incluyendo las partes que son realmente específicas de cada framework.
import { useEffect, useRef } from 'react';
import grapesjs, { type Editor } from 'grapesjs';
export function GjsEditor() {
const ref = useRef<HTMLDivElement>(null);
const editorRef = useRef<Editor | null>(null);
useEffect(() => {
if (!ref.current) return;
editorRef.current = grapesjs.init({
container: ref.current,
height: '100vh',
storageManager: false,
});
// GrapesJS owns this node now — React must never render into it again.
return () => {
editorRef.current?.destroy();
editorRef.current = null;
};
}, []);
return <div ref={ref} />;
}React
Construye un editor GrapesJS dentro de una aplicación React.
Guía ReactNext.js
Integra GrapesJS con una aplicación Next.js y arquitectura de editor en el lado del cliente.
Guía Next.jsVue
Añadir GrapesJS a una aplicación Vue.
Guía VueAngular
Integra GrapesJS con Angular.
Guía AngularVanilla JavaScript
Empieza con el núcleo GrapesJS API — sin framework, sin wrapper, sin necesidad de paso de compilación.
Documentos oficialesUna advertencia que afecta a todos en un framework renderizado por servidor: GrapesJS toca la ventana cuando carga el módulo, así que el editor tiene que importarse solo en el cliente. La guía de Next.js cubre exactamente eso.
Un editor de producción suele necesitar más que grapesjs.init(). No porque la biblioteca esté incompleta — porque un editor es una capa de un producto, y las capas que lo rodean son tuyas.
Una pila de producción típica
Nada de lo que sigue es una crítica a GrapesJS — es un framework de editores, y este es el lugar correcto para que se detenga. Conocer la línea antes de empezar es lo que evita que una compilación de tres semanas se convierta en una de nueve meses.
Ocho de estos son tuyos directamente. Esa es la forma honesta de la obra, y es la misma forma que elijas el editor visual.
El núcleo es el mismo para todos ellos. Lo que difiere es la capa que lo rodea — y cada uno de ellos tiene su propia guía.
Crea un editor visual para páginas de marketing.
Creador de landing pagesDeja que tus clientes creen páginas dentro de tu aplicación.
Creador de páginas SaaSAñade edición visual a un producto que ya existe.
Editor integrableCrea flujos de trabajo para diseñar emails.
Creador de emailsCrea tu propia experiencia de creación de páginas con tu marca.
Creador de marca blancaAñade edición visual a un sistema de contenidos headless.
Editor para CMS headlessCada una de estas cosas proviene del mismo lugar: tratar al editor como el producto en lugar de como una capa única.
Acabas añadiendo comportamiento a una entrada de paleta y preguntándote por qué no hace nada una vez que el objeto está en el lienzo.
Un bloque solo crea cosas. Todo comportamiento — traits, bloqueos, renderizado, validación — pertenece al tipo de componente que crea.
El almacenamiento predeterminado escribe en localStorage. Parece que se guarda hasta que un lector cambia de dispositivo, borra su navegador o abre el mismo proyecto en dos pestañas.
Decide dónde están realmente los proyectos antes de que alguien produzca contenido, y pon storageManager: false hasta que lo hayas hecho.
El trabajo persiste silenciosamente en una tienda que nunca diseñaste, y el orden de carga se vuelve impredecible una vez que existen varios proyectos.
Configura el almacenamiento remoto, registra uno personalizado o guarda el disco y carga con getProjectData() y loadProjectData().
Cuarenta tipos casi idénticos, cada uno con su propio traits, y una paleta que nadie puede navegar.
Prefiero un tipo con traits antes que cinco tipos que difieran por un color. Extiende los tipos integrados en lugar de reconstruirlos.
Los autores optan por float, posicionamiento absoluto y márgenes de 13px, y cada página se aleja más del sistema de diseño.
Lista tus sectores explícitamente y usa stylable / unstylable por componente. Menos controles producen mejores páginas.
Semanas perdidas buscando usuarios, roles, flujos de trabajo y funciones de publicación que nunca estuvieron ahí.
Lee primero la división de responsabilidades en el paso 12. GrapesJS es la capa de edición; el CMS que la rodea es tu producto.
Sin la subida configurada, las imágenes se incrustan como base64 y el proyecto almacenado crece hasta que carga lenta y es incómodo moverse.
Conecta el Asset Manager a un almacenamiento real desde el primer día, aunque ese almacenamiento sea una carpeta en el disco.
Tienes un editor que guarda y no hay respuesta a "¿cómo se convierte esto en una página que un visitante puede abrir?".
Haz un boceto de la pipeline desde el paso 8 antes de construir el editor. Normalmente cambia lo que almacenas.
Un único archivo de 2.000 líneas que registra bloques, tipos, paneles y comandos, y que no puede ser reutilizado ni probado en piezas.
Un plugin por preocupación. Componen, y a cada uno se le pueden dar opciones.
Páginas que parecen directamente en el lienzo del escritorio y se rompen en un teléfono, con cientos de reglas solo para escritorio ya escritas.
Cambia de dispositivo mientras construyes. Los estilos se escriben por dispositivo, así que crear a un ancho se hornea ese ancho.
Las cinco cosas que más probablemente fallarán en una primera construcción, y qué comprobar en cada una.
Normalmente es un problema de montaje más que un problema de GrapesJS.
Comprueba
Hay dos hojas de estilo diferentes y es fácil cargar ninguna.
Comprueba
Escucha storage:error — GrapesJS informa de fallos en lugar de aceptarlos.
Comprueba
Casi siempre es un problema del ciclo de vida, no uno de GrapesJS.
Comprueba
GrapesJS toca la ventana cuando se evalúa el módulo, por lo que no puede importarse durante el renderizado del servidor.
Comprueba
A dónde ir una vez que el editor anterior tenga sentido, más o menos en orden de dificultad.
El bucle central: poner un editor en pantalla y poner cosas en él.
Hacer el editor tuyo: tipos personalizados, plugins, almacenamiento y herramientas.
Todo lo relacionado con el editor: arquitectura, arrendamiento, publicación y producción.
Esta página es la construcción: instalar, configurar, extender, enviar. La guía completa es la referencia — la arquitectura, el ecosistema y la razón detrás del diseño. La mayoría de la gente acaba leyendo ambos, en ese orden.
Lee la guía completaLa mayor parte de este tutorial es un día de trabajo. La capa debajo — almacenamiento, arrendamiento, publicación, un editor que se ajuste a tu sistema de diseño — es donde los proyectos se hacen largos. GJS.Market puede asumir esa parte.
Empieza con el editor principal, personalízalo para tu producto y amplíalo con plugins e integraciones cuando necesites más funcionalidad.
Instala GrapesJS y ten un editor abierto en los próximos diez minutos.
Ve al paso 1Bloques, componentes, almacenes y proveedores de recursos del catálogo GJS.Market.
Explorar pluginsComponentes personalizados, integración de almacenamiento y arquitectura de producción, hechos contigo.
HáblanosTodas las muestras de esta página se han comprobado con GrapesJS 0.23.6 en 2026-09-03.