Lanza un creador de páginas pulido sin pelear con SSR.
GrapesJS es solo para navegador, mientras que Next.js se renderiza en el servidor por defecto. Esta guía te ofrece la arquitectura más segura para el arranque solo de un editor de cliente, APIs estables de guardado/publicación y una experiencia de usuario que los usuarios pueden aprender rápidamente.
Lista rápida de verificación de implementación
- Ejecuta npm, instala grapesjs y carga estilos una vez globalmente
- Mantén la inicialización del editor en un componente solo de cliente
- Desactiva el SSR usando la importación dinámica con { ssr: false }
- Añade guardado automático a la ruta de la API y versiona tus cargas útiles de contenido
- Renderizar HTML/CSS publicado en una ruta de visor sanitizada
Importante: GrapesJS es solo para navegador
GrapesJS llama a APIs de navegador (document, window, requestAnimationFrame) en la inicialización. Debes usar dynamic() con { ssr: false } en el Enrutador de Páginas, o en el 'use client' directiva con un isMounted Guarda en el Router de Aplicaciones. Saltarse esto provocará un error en tiempo de compilación o de ejecución.
Patrón solo para el lado del cliente
El enfoque recomendado tanto para Pages Router como para App Router es dividir el editor en dos archivos: un wrapper fino que utiliza dynamic para desactivar SSR, y un componente solo cliente que inicializa GrapesJS:
// components/GrapesJSEditor.tsx
import dynamic from 'next/dynamic';
const GrapesEditor = dynamic(
() => import('./GrapesEditorClient'),
{ ssr: false, loading: () => <div>Loading editor...</div> }
);
export default function GrapesJSEditor() {
return <GrapesEditor />;
}
// components/GrapesEditorClient.tsx
import { useEffect, useRef } from 'react';
import grapesjs from 'grapesjs';
export default function GrapesEditorClient() {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const editor = grapesjs.init({
container: ref.current!,
storageManager: false,
});
return () => editor.destroy();
}, []);
return <div ref={ref} style={{ height: '100vh' }} />;
}Router de aplicaciones vs router de páginas
Router de páginas (Next.js 13/12)
Uso dynamic() de next/dynamic con { ssr: false }. Todos los componentes son componentes cliente de React por defecto, por lo que el único requisito es desactivar SSR para GrapesJS.
Router de aplicaciones (Next.js 13+)
Añadir 'use client' En la parte superior de tu componente de edición. Aún puedes usar dynamic() para el estado de carga, o añadir un isMounted State Guard para evitar el renderizado hasta que el componente se haya montado en el lado del cliente.
Elige tu alcance de lanzamiento
MVP en 1-2 días
Usa bloques por defecto, persistencia local y un punto final de publicación. Es ideal para herramientas internas o pruebas tempranas con clientes.
Lanzamiento de producción en 1-2 semanas
Añadir permisos de bloque, guardado automático, subidas de recursos, historial de revisiones y flujos de trabajo de publicación basados en roles.
Plataforma constructora SaaS
Almacenamiento multiinquilino, mercado de plantillas, cuotas de uso, registros de auditoría y branding a nivel de espacio de trabajo.
Guía de integración paso a paso
Instalar GrapesJS
Ejecuta npm install grapesjs en tu proyecto Next.js. Se incluyen los tipos de TypeScript.
Crea un componente editor solo para cliente
Crea GrapesEditorClient.tsx que inicialice GrapesJS en un gancho useEffect con una referencia DOM.
Envuelva con siguiente/dinámico (ssr: false)
Utiliza dynamic(() => import("./GrapesEditorClient"), { ssr: false }) para evitar la ejecución en servidor.
Conectar almacenamiento a una ruta API
Utiliza editor.getHTML() y editor.getCSS() para publicar contenido en una ruta API Next.js, Vercel KV o Supabase.
Plugins recomendados para proyectos Next.js
API REST de almacenamiento
Conecta GrapesJS a rutas API Next.js para persistencia
Bloques Biblioteca Pro
Biblioteca de bloques lista para producción para constructores de páginas Next.js
Preajuste GrapesJS MJML
Crea plantillas de correo responsivas en tu aplicación Next.js
Plugin de exportación
Exportar HTML/CSS limpio desde Next.js rutas API
Ejemplos de integración de almacenamiento
Vercel KV
// Save to Vercel KV
import { kv } from '@vercel/kv';
export async function POST(req: Request) {
const { id, html, css } = await req.json();
await kv.set(`page:${id}`, { html, css });
return Response.json({ ok: true });
}Supabase
// Save to Supabase
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_KEY!
);
export async function savePage(id: string, html: string, css: string) {
await supabase.from('pages').upsert({ id, html, css });
}Guías relacionadas
¿Listo para lanzar tu experiencia visual builder?
Empieza con plugins probados en batalla y luego superpone tus propios flujos de trabajo para equipos, clientes y aprobaciones de publicación.
Explorar la pila de plugins