Integración directa
Importa grapesjs, llama a grapesjs.init() en onMounted(), llama a editor.destroy() en onUnmounted(). No hay dependencia extra, nada entre tú y la API del editor.
PageKit: el creador de sitios GrapesJS autoalojado, con el código fuente incluido. Obtener acceso anticipado
Integra el editor visual de código abierto GrapesJS en aplicaciones Vue 3 y Nuxt para crear constructores visuales de páginas, editores CMS, creadores de páginas de destino, editores de correo electrónico y experiencias de edición de marca blanca.
La división merece la pena nombrar antes que cualquier código. Tu aplicación Vue se encarga del enrutamiento, usuarios, permisos y datos. GrapesJS es dueño del lienzo y de todo lo que una persona manipula dentro de él. Ambos se encuentran en un nodo DOM y una llamada de guardado.
Nada en esa cadena requiere que Vue sepa cómo funciona el editor, y nada requiere que GrapesJS sepa que está dentro de una app Vue. Por eso la integración es corta.
Sí. GrapesJS es independiente del framework y puede integrarse directamente en aplicaciones Vue 3. Puedes inicializar el editor con ganchos de ciclo de vida Vue, mantener la instancia del editor en un composable o componente, conectar eventos GrapesJS a tu aplicación Vue y persistir los datos del proyecto a través de tu propio backend.
Importa grapesjs, llama a grapesjs.init() en onMounted(), llama a editor.destroy() en onUnmounted(). No hay dependencia extra, nada entre tú y la API del editor.
Envuelva ese ciclo de vida en tu propio composable — o en un paquete comunitario — para que los componentes tengan una API con forma de Vue en lugar de una imprescindible. Útil cuando más de una pantalla monta un editor.
GrapesJS publica un wrapper oficial de framework, @grapesjs/react, para React. No existe un paquete equivalente de Vue del proyecto GrapesJS, así que cualquier wrapper de Vue que encuentres en npm es un proyecto comunitario. Consulta sus rangos de pares Vue y GrapesJS antes de adoptarlo.
Vue 3 es un framework de aplicaciones. GrapesJS es un motor de edición visual. Resuelven diferentes problemas y la integración es limpia precisamente porque no se solapan.
Cinco de estos son tuyos. El resto ya existe, y los dos restantes son de configuración y no de construcción.
Una dependencia. GrapesJS incluye sus propias definiciones de TypeScript, así que no hay un paquete de @types separado para añadir.
npm install grapesjsEl editor no tiene estilo sin ella. En un proyecto Vite o Nuxt puedes importarlo desde el componente o composable que crea el editor; en una app con hoja de estilo global, impórtalo una vez que esté allí.
Copia esto en un componente y se ejecuta. Todo lo que viene después de esta sección es una adición, no una reescritura.
<template>
<div ref="editorContainer" class="editor-shell"></div>
</template>
<script setup lang="ts">
import { onMounted, onUnmounted, shallowRef, ref } from 'vue';
import grapesjs, { type Editor } from 'grapesjs';
import 'grapesjs/dist/css/grapes.min.css';
// A template ref: the name matches the ref="" attribute above.
const editorContainer = ref<HTMLDivElement | null>(null);
// shallowRef, not ref — see "Performance" further down the page.
const editor = shallowRef<Editor | null>(null);
onMounted(() => {
if (!editorContainer.value) return;
editor.value = grapesjs.init({
container: editorContainer.value,
height: '100%',
fromElement: false,
storageManager: false,
});
});
onUnmounted(() => {
editor.value?.destroy();
editor.value = null;
});
</script>
<style scoped>
.editor-shell {
height: 100vh;
}
</style>El nombre de referencia de la plantilla coincide con el atributo ref="" — así es como Vue los encaja en <script setup>.
El editor está en shallowRef, no en ref. Vue de lo contrario recorrería todo el grafo de objetos del editor haciéndolo reactivo.
fromElement es falso, así que GrapesJS empieza desde los componentes que pasas en lugar de desde el marcado que había dentro del contenedor.
Toda la integración es un mapeo del ciclo de vida. Vue te dice cuándo existe el nodo DOM y cuándo está a punto de desaparecer; GrapesJS necesita exactamente esos dos momentos.
Lee de arriba a abajo, ese es todo el contrato entre las dos bibliotecas.
Ni onMounted ni onUnmounted se ejecutan en el servidor, por eso una SPA Vue simple no necesita nada extra. Una aplicación renderizada en servidor necesita un protector más — la sección Nuxt lo cubre.
Cuando una segunda pantalla necesite un editor, mueve el ciclo de vida a un composable. El componente entonces dice lo que quiere, no cómo está cableado el editor.
// composables/useGrapesJS.ts
import { onMounted, onUnmounted, shallowRef, type Ref } from 'vue';
import grapesjs, { type Editor, type EditorConfig } from 'grapesjs';
import 'grapesjs/dist/css/grapes.min.css';
type EditorOptions = Omit<EditorConfig, 'container'>;
export function useGrapesJS(
container: Ref<HTMLElement | null>,
options: EditorOptions = {},
) {
const editor = shallowRef<Editor | null>(null);
const init = (): Editor | undefined => {
if (editor.value || !container.value) return;
editor.value = grapesjs.init({
container: container.value,
height: '100%',
fromElement: false,
storageManager: false,
...options,
});
return editor.value;
};
const destroy = (): void => {
editor.value?.destroy();
editor.value = null;
};
onMounted(init);
onUnmounted(destroy);
return { editor, init, destroy };
}<template>
<div ref="editorContainer" class="editor-shell"></div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useGrapesJS } from '~/composables/useGrapesJS';
const editorContainer = ref<HTMLElement | null>(null);
const { editor } = useGrapesJS(editorContainer, {
blockManager: {
blocks: [
{
id: 'hero',
label: 'Hero',
category: 'Sections',
content: '<section>…</section>',
},
],
},
});
</script>Resiste que esto crezca más de lo necesario. Un composable que envuelve cada módulo GrapesJS en una fachada reactiva es una segunda API para aprender y una segunda cosa para mantener sincronizada.
GrapesJS gestiona el estado del editor. Vue gestiona el estado de la aplicación. Los eventos son la costura: suscríbete a los pocos que tu interfaz realmente refleja y escríbelos en referencias normales.
import { onMounted, ref, shallowRef } from 'vue';
import type { Editor, Component } from 'grapesjs';
const isReady = ref(false);
const isDirty = ref(false);
const saveState = ref<'idle' | 'saving' | 'saved' | 'error'>('idle');
const selectedName = ref<string | null>(null);
function bindEditorEvents(editor: Editor): void {
editor.on('load', () => {
isReady.value = true;
});
editor.on('component:selected', (component: Component) => {
selectedName.value = component?.getName?.() ?? null;
});
editor.on('component:update', () => {
isDirty.value = true;
});
editor.on('storage:start:store', () => {
saveState.value = 'saving';
});
editor.on('storage:end:store', () => {
saveState.value = 'saved';
isDirty.value = false;
});
editor.on('storage:error', () => {
saveState.value = 'error';
});
}| Evento | Qué hace tu interfaz con él |
|---|---|
| load | Oculta el estado de carga una vez que el proyecto esté en el lienzo |
| component:selected | Muestra qué elemento está seleccionado en tu propia barra de herramientas |
| component:update | Marca el documento como sucio, activa el botón de guardar |
| storage:start:store | Mostrar un indicador de ahorro |
| storage:end:store | Show salvado, despejad la bandera sucia |
| storage:error | Superar un fallo sobre el que el usuario puede actuar |
Imita lo que muestras, no lo que tenga el editor. Copiar el árbol de componentes en una tienda Vue te da dos fuentes de verdad y un error de sincronización.
GrapesJS depende de las APIs DOM del navegador, así que la inicialización del editor solo debería ocurrir en un contexto de navegador. En Nuxt eso significa mantener el editor fuera del renderizado del servidor — todo lo demás es la misma integración que ya tienes.
<!-- pages/editor.vue -->
<template>
<ClientOnly>
<VisualEditor />
<template #fallback>
<p class="editor-placeholder">Loading the editor…</p>
</template>
</ClientOnly>
</template><!-- components/VisualEditor.client.vue -->
<template>
<div ref="editorContainer" class="editor-shell"></div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useGrapesJS } from '~/composables/useGrapesJS';
// Reached only in the browser: the .client suffix keeps this
// component out of the server render, and onMounted never runs
// on the server anyway.
const editorContainer = ref<HTMLElement | null>(null);
const { editor } = useGrapesJS(editorContainer);
</script>Envuelve el editor donde se usa. La ranura de respaldo le da al servidor algo para renderizar, así que no hay fotograma en blanco antes de la hidratación.
La propia convención de nombres de Nuxt: un componente cuyo nombre de archivo termina en .client solo se renderiza en el navegador. Útil cuando el editor se usa en varios lugares.
Ambos son válidos y se combinan. Ninguno es necesario para GrapesJS — lo que GrapesJS requiere es simplemente que init() se ejecute donde existe el documento.
SSR renderiza el shell de la aplicación. GrapesJS se ejecuta en el navegador. Nombrar ese límite es lo que hace que una integración con Nuxt sea predecible en lugar de ser una fuente de errores de hidratación.
La pantalla del editor no es una página que renderizas en servidor para SEO, es una herramienta autenticada. Las páginas que produce son las que renderizas e indexas, y esas son HTML y CSS simples.
Crea un creador de páginas Vue completo →No. La integración directa es una forma completa y soportada de usar GrapesJS, y es lo que hacen los ejemplos de esta página. Un envoltorio es una comodidad, no un requisito.
| Enfoque | Mejor para | Compensación |
|---|---|---|
| GrapesJS directo | Control máximo | Tú mismo escribes el ciclo de vida — unas quince líneas. |
| Envoltorio / integración Vue | Una API más orientada a Vue | Una dependencia entre tú y la API del editor, en el calendario de lanzamientos de otra persona. |
| Composición personalizada | Integración de aplicaciones reutilizables | Es tuyo para mantener — pero es el archivo que se muestra arriba, y no se vuelve obsoleto. |
Vale la pena comprobarlo antes de adoptar nada, porque los resultados de búsqueda de esta pregunta son más antiguos que los paquetes que describen.
Comprobado con el registro npm en 2026-09-02. Si encuentras un paquete Vue más reciente, lee primero su peerDependencies: ese campo te indica si apunta a Vue 3 y a un GrapesJS actual.
Para Vue 3 hoy, el componible anterior es el envoltorio. Son unas veinte líneas, usa directamente la API de GrapesJS y no puede quedarse atrás de una versión de la que dependes.
Montar el editor es la primera tarde. Un creador de páginas en el que tus usuarios confíen es el resto del trabajo, y en su mayoría es la configuración de los módulos que GrapesJS ya extiene.
Canvas
La superficie editable y los anchos de sus dispositivos.
Components
Los tipos que tus usuarios pueden situar y sus rasgos.
Blocks
La paleta de la que se arrastran.
Style Manager
Qué propiedades CSS están expuestas y a quién.
Asset Manager
Imágenes y medios, desde tu almacenamiento.
Storage Manager
Donde se cargan y guardan los datos del proyecto.
Commands
Acciones nombradas, vinculables a tu propia interfaz.
Device Manager
Puntos de interrupción responsivos para la edición y la producción.
Plugins
Todo lo anterior, empaquetado y reutilizable.
El mismo núcleo del editor, configurado de forma diferente. Cada uno de estos es un conjunto distinto de bloques, un destino de almacenamiento distinto y un paso de publicación distinto.
Crea edición visual de página dentro de tu aplicación Vue.
Leer másProporciona a los equipos de contenido una interfaz visual de edición sobre las páginas que tu sitio Nuxt ya renderiza.
Leer másCrea diseños de marketing reutilizables que tu equipo de crecimiento pueda montar sin necesidad de despliegue.
Leer másCrea plantillas de correo visualmente, con la salida diseñada para clientes de correo en lugar de navegadores.
Leer másIntegra un editor de marca en tu producto, bajo tu propia interfaz y permisos.
Leer másDa a los usuarios control visual sobre HTML y CSS, y devuélvelo exactamente eso.
Leer másTres cosas que son fáciles de confundir y caras de confundir. Acertar desde el primer día es lo que hace que un documento pueda ser reeditado un año después.
El estado editable del proyecto GrapesJS — páginas, componentes, estilos, recursos. Léelo con editor.getProjectData(), restaura con editor.loadProjectData(). Esto es lo que debe persistir.
El marcado renderizado, de editor.getHtml(). Regéneralo cada vez que publiques. Es la salida, no la fuente.
Los estilos que produjo el editor, de editor.getCss(). La misma regla: generado, no almacenado como fuente de verdad.
Almacena datos editables del proyecto. Genera HTML y CSS cuando necesites renderizar o publicar.
Guardar solo el HTML renderizado es el error que no se puede deshacer después. Siempre puedes regenerar HTML a partir de datos del proyecto; no puedes recuperar datos del proyecto de forma fiable desde HTML.
// Editable state — store this, it is what the editor reloads.
const projectData = editor.getProjectData();
// Rendered output — regenerate this whenever you publish.
const html = editor.getHtml();
const css = editor.getCss();
await fetch(`/api/projects/${projectId}/publish`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ projectData, html, css }),
});
// Sanitize `html` on the server before it is served to anyone.A GrapesJS no le importa cuál sea tu backend. Un adaptador de almacenamiento son dos funciones asíncronas — una que devuelve los datos del proyecto y otra que los acepta — así que el editor se comunica con la API que ya tienes.
import grapesjs, { type ProjectData } from 'grapesjs';
// Wherever your app keeps it — a route param, a prop, a store.
const projectId = props.projectId;
const editor = grapesjs.init({
container: editorContainer.value!,
fromElement: false,
storageManager: {
type: 'app-api',
autosave: true,
stepsBeforeSave: 10,
},
// Registered as a plugin so the adapter exists before
// GrapesJS performs its first load.
plugins: [
(ed) => {
ed.Storage.add('app-api', {
async load(): Promise<ProjectData> {
const res = await fetch(`/api/projects/${projectId}`);
if (!res.ok) {
throw new Error(`Load failed: ${res.status}`);
}
return await res.json();
},
async store(data: ProjectData) {
const res = await fetch(`/api/projects/${projectId}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ projectData: data }),
});
if (!res.ok) {
throw new Error(`Save failed: ${res.status}`);
}
},
});
},
],
});Registrar el adaptador a través del array de plugins importa: garantiza que el almacenamiento exista antes de que GrapesJS realice su primera carga.
El gestor de activos es una interfaz de usuario sobre un endpoint. Apúntalo a la tuya y todas las reglas existentes — autenticación, validación, cuotas, CDN — siguen aplicándose.
// Fetched from your own API before the editor is created.
const assets = await fetch('/api/assets').then((res) => res.json());
const editor = grapesjs.init({
container: editorContainer.value!,
assetManager: {
assets,
// Uploads go to your endpoint, with your auth and
// your validation.
upload: '/api/assets',
uploadName: 'files',
multiUpload: true,
autoAdd: true,
headers: { Authorization: `Bearer ${token.value}` },
credentials: 'same-origin',
// Reject what the backend would reject anyway,
// before the round trip.
beforeUpload: (files: File[]) => {
const limit = 5 * 1024 * 1024;
const tooBig = files.some((f) => f.size > limit);
if (tooBig) {
toast.error('Images must be under 5 MB');
return false;
}
},
},
});Un tipo de componente personalizado es la forma en que el editor aprende tu producto. Tiene su propio panel de ajustes, sus propias reglas de caída y su propio bloque en la paleta.
import type { Editor } from 'grapesjs';
export function pricingCardPlugin(editor: Editor): void {
editor.Components.addType('pricing-card', {
isComponent: (el) => el.dataset?.gjsType === 'pricing-card',
model: {
defaults: {
tagName: 'section',
attributes: { 'data-gjs-type': 'pricing-card' },
// Traits become the settings panel for this component.
traits: [
{ type: 'text', name: 'plan', label: 'Plan name' },
{ type: 'text', name: 'price', label: 'Price' },
{ type: 'checkbox', name: 'featured', label: 'Featured' },
],
components: `
<h3 data-gjs-type="text">Starter</h3>
<p data-gjs-type="text">$0 / month</p>
<a href="#">Choose plan</a>
`,
},
},
});
editor.Blocks.add('pricing-card', {
label: 'Pricing card',
category: 'Marketing',
content: { type: 'pricing-card' },
});
}
// Pass it to the editor like any other plugin:
// grapesjs.init({ container, plugins: [pricingCardPlugin] })Los componentes personalizados también son la forma de restringir el editor. Configurar desplegable o arrastrable en un tipo es lo que impide que un usuario deje caer una tarjeta de precios dentro de una barra de navegación, y los rasgos son los que le dan un campo etiquetado en lugar de un control CSS en bruto.
Estos son tipos de componentes GrapesJS, no componentes Vue. El lienzo renderiza DOM; tus componentes Vue renderizan tu aplicación alrededor de él.
Un plugin es una función que recibe el editor — la misma firma de función, ya sea que venga de npm, de GJS.Market o de tu propio repositorio. A ninguno le importa que la aplicación anfitriona sea Vue.
import grapesjs from 'grapesjs';
import basicBlocks from 'grapesjs-blocks-basic';
import { pricingCardPlugin } from '~/editor/pricing-card';
const editor = grapesjs.init({
container: editorContainer.value!,
plugins: [
// Options go through a wrapper function: `pluginsOpts`
// is keyed by string, so it only reaches plugins that
// were passed to `plugins` by name.
(ed) => basicBlocks(ed, { flexGrid: true }),
pricingCardPlugin,
],
});La paleta, la edición de texto y los controles de formulario que hacen que el lienzo sea útil desde el primer día.
Navegar categoríaUna paleta inicial para que el lienzo no quede vacío la primera vez que un usuario lo abra.
Secciones en forma de Tailwind, para equipos cuya salida ya utiliza Tailwind.
Una barra de herramientas de texto en línea más rica que la integrada.
Campos de formulario como componentes editables, con el panel de rasgos para sus atributos.
Persistencia, guardado automático y recuperación por fallos — la parte que todo prototipo pospone.
Navegar categoríaVarios proyectos, listados y intercambiables, sin necesidad de escribir la interfaz de usuario para ello.
Persistencia local — útil para borradores, trabajo offline y un prototipo rápido.
Recupera trabajo no guardado tras un fallo o una pestaña cerrada.
Un adaptador de almacenamiento para equipos que ya ejecutan Directus como backend.
Manejo de medios y el paso entre un proyecto guardado y una página servida.
Navegar categoríaSubir y transformar a través de Cloudinary en lugar de tu propio pipeline.
Uppy como la interfaz de subida, con su gestión reanudable y multifuente.
Devuelve la página terminada como archivo descargable.
Señala problemas de accesibilidad y SEO antes de que una página se publique.
No es un argumento de que construir está mal, sino un inventario de lo que significa construir. Cada fila es un subsistema que existe, lo hayas planeado o no.
| Capacidad | Constrúete | GrapesJS |
|---|---|---|
| Canvas | Construcción | Incluido |
| Drag & drop | Construcción | Incluido |
| Components | Construcción | Incluido |
| Blocks | Construcción | Incluido |
| Style Manager | Construcción | Incluido |
| Asset Manager | Construcción | Extensible |
| Storage Manager | Construcción | Extensible |
| Plugins | Construir un ecosistema | Arquitectura de plugins |
| Vue integration | Nativo | Agnóstico respecto al marco |
Vue te da el marco de la aplicación. GrapesJS te da el motor de edición visual.
Porque los componentes de Vue son bloques constructores de aplicaciones, y un editor visual necesita algo más encima: gestión de canvas, un árbol de componentes con reglas de drop, selección y estado de hover, una capa de estilo que escriba CSS real, cambio de dispositivo, deshacer y rehacer todo eso, gestión de activos, serialización, comandos con nombre y un punto de extensión para todo. Puedes construir eso en Vue — simplemente es un proyecto diferente al que te propusiste.
Vue + GrapesJS es una propuesta diferente a los componentes Vue por sí solos.
Tu aplicación Nuxt o Vue: el shell, la sesión y quién puede abrir qué proyecto.
El editor, montado en una pantalla. Recibe un proyecto y emite un proyecto.
Tus propias rutas. GrapesJS los llama a través de los adaptadores de almacenamiento y activos que has escrito.
Donde realmente viven proyectos, medios, usuarios y versiones — sin cambios por el editor que está encima.
El editor es una hoja en ese árbol, no la raíz. Todo lo que está encima es código que habrías escrito de todas formas.
No hagas que el editor reaccione profundamente
Este es el que realmente muerde. shallowRef, o una variable con alcance de módulo — nunca ref() alrededor de la instancia del editor. Vue recorrería un grafo de objetos muy grande y reejecutaría efectos sobre el churn interno.
Inicializar solo cuando sea necesario
Crea el editor en la pantalla que edita, no en un layout o un almacén que monten todas las rutas.
Carga perezosamente el editor
GrapesJS es un paquete considerable. Cárgalo en su propio bloque asíncrono para que las rutas que nunca editen nunca paguen por ello.
Mantén las actualizaciones fuera del estado global
Enviar cada component:update a una tienda convierte cada pulsación de tecla en un renderizado a nivel de aplicación.
Paginar colecciones de grandes activos
Semilla el gestor de activos desde un endpoint paginado en lugar de enviar miles de URLs al editor.
Mantén los árboles de componentes manejables
Los documentos muy profundos cuestan más de renderizar, serializar y diferenciar. La estructura se fomenta a sí misma si tus bloques lo hacen.
Un editor visual es un sistema que acepta HTML creado por el usuario. Trátalo así.
Casi todos los problemas de integración reportados para esta combinación son uno de estos siete.
Síntoma
El contenedor es nulo, o el editor se renderiza en nada.
Arreglar
Crea el editor dentro de onMounted(). La referencia de la plantilla no tiene ningún elemento antes de eso.
Síntoma
La memoria crece y los oyentes aburridos disparan tras abandonar la ruta.
Arreglar
Llama a editor.destroy() en onUnmounted() y borra la referencia.
Síntoma
El editor se siente lento; las herramientas de desarrollo de Vue se estancan.
Arreglar
Mantén la instancia en shallowRef, o fuera completamente de la reactividad Vue.
Síntoma
El documento no está definido, o hay una descoordinación de hidratación en la ruta del editor.
Arreglar
Renderiza el editor solo para el cliente — <ClientOnly>, un componente .client, o ambos.
Síntoma
Dos fuentes de verdad, y ediciones que desaparecen en la navegación.
Arreglar
Deja que GrapesJS sea el dueño del proyecto; refleja solo los pocos valores que muestra tu interfaz.
Síntoma
El editor carga, pero los paneles no tienen estilo ni se pueden usar.
Arreglar
Importa grapesjs/dist/css/grapes.min.css, o inclúyelo en tu hoja de estilos global.
Síntoma
Errores de tipo, o una integración basada en ganchos de ciclo de vida Vue 2.
Arreglar
Revisa peerDependencies antes de adoptar cualquier envoltorio. Varios ejemplos populares son anteriores a Vue 3.
En Vue 2 la misma integración usa mounted() y beforeDestroy() en lugar de onMounted() y onUnmounted(); el lado GrapesJS no ha cambiado. El nuevo trabajo debería dirigirse a Vue 3 — todo en esta página lo asume.
El orden coincide más o menos con el orden en que esta página los presentó.
Sí. GrapesJS es una biblioteca independiente del framework que se renderiza en un elemento DOM, así que funciona en Vue 3 sin adaptador. Inicialízalo en onMounted() y destrúyelo en onUnmounted().
Ejecuta npm e instala grapesjs. El paquete incluye sus propias definiciones TypeScript. También necesitas cargar su hoja de estilo, ya sea importando grapesjs/dist/css/grapes.min.css o incluyéndolo en tu CSS global.
Crea una referencia plantilla en el elemento contenedor y luego llama a grapesjs.init({ container: containerRef.value }) dentro de onMounted(). El elemento no existe antes de montar, así que inicializar cualquier elemento anterior no da a GrapesJS nada en qué renderizar.
Sí, y es la forma recomendada. onMounted() y onUnmounted() se asignan directamente a grapesjs.init() y editor.destroy(), y toda la integración cabe en un único composable.
Sí. Todos los ejemplos en esta página usan <script setup lang="ts">. Una referencia plantilla declarada con ref() se vincula automáticamente al atributo ref="" correspondiente.
Sí. La integración es idéntica a la del Vue 3 simple; la única novedad es mantener el editor fuera del renderizado del servidor, con <ClientOnly> o un componente .client.
Sí, con el editor renderizado solo por cliente. GrapesJS necesita APIs DOM de navegador, así que no puede ejecutarse durante un renderizado en servidor — pero las páginas que produce son HTML y CSS simples, y esas son exactamente las que renderizas e indexas en servidor.
No. La integración directa es un enfoque completo y es lo que usan los ejemplos aquí. GrapesJS publica un envoltorio oficial de React pero no un equivalente a Vue, así que cualquier envoltorio de Vue en npm es un proyecto comunitario — revisa sus rangos de pares Vue y GrapesJS antes de adoptarlo.
Sí. GrapesJS incluye las definiciones de TypeScript en el paquete, así que el tipo Editor y el objeto de configuración se tipifican sin una dependencia @types adicional.
Sí. Registra un adaptador de almacenamiento con editor.Storage.add() que implemente load() y store(). Ambos son funciones asíncronas ordinarias, así que pueden llamar a la API que ya tengas.
Sí. editor.Components.addType() define un tipo de componente con sus propios rasgos y reglas de drop, y editor.Blocks.add() lo coloca en la paleta. Así es como el editor aprende el vocabulario de tu producto.
Sí. Un plugin GrapesJS es una función que recibe la instancia del editor, así que no se ve afectada por el framework que la aloja. Pasa plugins en el array de plugins de grapesjs.init().
Sí — ese es el caso común. Montar el editor es la parte corta; el resto consiste en configurar bloques, almacenamiento, recursos y permisos alrededor de él.
Integra el motor de edición visual en tu aplicación Vue o Nuxt, mantén el control de tus datos y salidas, y amplía el editor con los plugins que tu producto necesite.
Construye tu aplicación con Vue 3. Añade edición visual con GrapesJS.