Ship a polished page builder without fighting SSR.
GrapesJS is browser-only, while Next.js renders on server by default. This guide gives you the safest architecture for client-only editor boot, stable save/publish APIs, and a UX users can learn quickly.
Quick implementation checklist
- Run npm install grapesjs and load styles once globally
- Keep editor initialization in a client-only component
- Disable SSR using dynamic import with { ssr: false }
- Add autosave to API route and version your content payloads
- Render published HTML/CSS in a sanitized viewer route
Important: GrapesJS is browser-only
GrapesJS calls browser APIs (document, window, requestAnimationFrame) on initialisation. You must use dynamic() with { ssr: false } in the Pages Router, or the 'use client' directive with an isMounted guard in the App Router. Skipping this will cause a build-time or runtime error.
Client-Side Only Pattern
The recommended approach for both Pages Router and App Router is to split the editor into two files: a thin wrapper that uses dynamic to disable SSR, and a client-only component that initialises 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' }} />;
}App Router vs Pages Router
Pages Router (Next.js 12/13)
Use dynamic() from next/dynamic with { ssr: false }. All components are React Client Components by default, so the only requirement is disabling SSR for GrapesJS.
App Router (Next.js 13+)
Add 'use client' at the top of your editor component. You can still use dynamic() for the loading state, or add an isMounted state guard to prevent rendering until the component has mounted client-side.
Choose your launch scope
MVP in 1-2 days
Use default blocks, local persistence, and one publish endpoint. Best for internal tools or early customer trials.
Production launch in 1-2 weeks
Add block permissions, autosave, asset uploads, revision history, and role-based publishing workflows.
SaaS builder platform
Multi-tenant storage, template marketplace, usage quotas, audit logs, and workspace-level branding.
Step-by-Step Integration Guide
Install GrapesJS
Run npm install grapesjs in your Next.js project. TypeScript types are included.
Create a client-only editor component
Create GrapesEditorClient.tsx that initialises GrapesJS in a useEffect hook with a DOM ref.
Wrap with next/dynamic (ssr: false)
Use dynamic(() => import("./GrapesEditorClient"), { ssr: false }) to prevent server-side execution.
Connect storage to an API route
Use editor.getHTML() and editor.getCSS() to post content to a Next.js API route, Vercel KV, or Supabase.
Recommended Plugins for Next.js Projects
Storage REST API
Connect GrapesJS to Next.js API routes for persistence
Blocks Library Pro
Production-ready block library for Next.js page builders
GrapesJS MJML Preset
Build responsive email templates in your Next.js app
Export Plugin
Export clean HTML/CSS from within Next.js API routes
Storage Integration Examples
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 });
}Related Guides
Ready to launch your visual builder experience?
Start with battle-tested plugins, then layer your own workflows for teams, clients, and publishing approvals.
Explore plugin stack