PageKit — the self-hosted GrapesJS site builder, sold as source. Get early access

Headless CMS Editor

Headless CMS Visual Editor with GrapesJS

Add a visual drag-and-drop editor to your headless CMS while keeping your existing content API, frontend and infrastructure.

Visual drag & dropCustom componentsReusable blocksREST & GraphQLYour CMSYour frontendYour data
A visual editing layer over an existing content API: the component library on the left, the page on the canvas, the selected component's properties on the right.
See it running

This is the editing surface you are adding

The screen above is a mock-up of the arrangement, drawn in CSS so it costs the page nothing. The editor engine behind it is real and public: open the official GrapesJS demo, drag a section onto the canvas, and you are looking at the same canvas, component tree and style controls your content team would get on top of your own CMS.

Try the editor

The demo runs on grapesjs.com with browser storage. Nothing on it touches your content.

The value

Give your headless CMS a visual editing experience

A headless CMS gives your application an API-first content foundation. What it does not always give the people writing the content is a way to see the page while they build it.

Structured fields are excellent for an article, a product record or a settings document. They are a poor fit for a page whose meaning is its layout — a campaign page, a feature tour, a pricing comparison. For those, the people doing the work usually ask for the same short list:

What editors ask for

  • a visual canvas
  • drag & drop
  • reusable page sections
  • responsive editing
  • templates
  • component configuration
  • live preview

GrapesJS provides that visual editing layer without forcing you to replace your CMS.

The gap

Headless CMS gives you content. Your users still need an editor.

A headless architecture separates content from presentation, which is exactly why it leaves an editing gap: the CMS knows the fields, the frontend knows the rendering, and nothing in between knows the page. Adding a visual editing layer closes that gap without unpicking either side.

Traditional headless CMS

  • CMS
  • Structured content
  • API
  • Frontend

Missing

  • Visual editing
  • Drag & drop
  • Page composition
  • Responsive design

Headless CMS + GrapesJS

  • CMS
  • Structured content
  • GrapesJS visual editor
  • API
  • Frontend
The same stack, with one layer added. Nothing above or below it changes.

Add visual editing without giving up the headless architecture.

Division of labour

Why add a visual editor to a headless CMS?

Because each of the three layers is good at something the other two are not, and a visual editing layer is the only one of them that nobody ships for you. Here is who owns what once the editor is in place.

  • Your headless CMS

    The content infrastructure you already run.

    • Content
    • Structured data
    • Media
    • Users
    • Publishing
    • APIs
  • GrapesJS

    The visual editing layer you are adding.

    • Visual canvas
    • Drag & drop
    • Components
    • Blocks
    • Styling
    • Responsive editing
    • Visual page composition
  • Your frontend

    Unchanged. It keeps everything it owned before.

    • Rendering
    • Routing
    • Application logic
    • User experience
    • Deployment

Keep the architecture. Upgrade the editing experience.

Architecture

How a headless CMS visual editor works

Four layers, in the order a save travels through them. The editor never talks to your database and never renders your production pages — it reads and writes one document through an endpoint you control.
  1. GrapesJS

    The visual editing experience: canvas, component tree, blocks, style controls, device widths.

  2. REST / GraphQL

    Persistence through REST, GraphQL or your own API. A storage adapter is two functions — one that loads, one that saves.

  3. Headless CMS

    Your existing content infrastructure. It keeps the schema, the media library, the users and the publishing rules it already has.

  4. Content API

    The delivery API your frontends already read from. Adding an editor adds a writer, not a second source of content.

  5. Delivery

    Any frontend that consumes your CMS API.

    • Next.js
    • Nuxt
    • React Native

One content source. Multiple frontends.

See how the editor embeds into an application
No migration

You don't need to replace your CMS

The editing layer attaches through the same API your frontend already calls. Whether you are running Strapi, Contentful, Sanity, Directus, Hygraph, Prismic, Payload or a CMS your own team wrote, the integration point is a pair of endpoints that load and save one document.

These platforms can be integrated through their APIs, with the exact implementation depending on the CMS content model and API. GJS.Market does not publish an official integration for most of them, and this page never implies otherwise.

Keep your CMS. Keep your frontend. Add a better visual editor.

Compatibility

Works with the CMS you already use

The cards below describe the integration surface each platform offers, not a support claim. One of them has a community storage plugin in the GJS.Market catalogue; the rest are integrations you or an implementation partner would build against their published API.

  • Strapi

    REST · GraphQL

    Self-hosted, with content types you define. The editor document usually becomes a JSON field on a page collection type.

  • Contentful

    REST · GraphQL

    Separate delivery and management APIs. The editor writes through the management API; your frontend keeps reading the delivery one.

  • Sanity

    GROQ · GraphQL

    Portable Text and a document store. The editor document sits alongside your existing fields rather than replacing them.

  • Directus

    REST · GraphQL

    The only platform on this list with a community storage plugin already published on GJS.Market.

    View the plugin
  • Hygraph

    GraphQL

    GraphQL-first, so the adapter is a query and a mutation instead of two URLs.

  • Prismic

    REST

    Slice-based content. Editor blocks map cleanly onto slices when you keep the block set aligned with them.

  • Payload

    REST · GraphQL

    Code-defined collections, so the field the editor writes to is declared in the same repository as the editor.

  • Custom CMS

    REST · GraphQL · custom

    Anything that can answer a load request and accept a save request. Two endpoints is the whole contract.

The one CMS-named adapter in the catalogue

Directus Storage is a free, community-published GrapesJS storage plugin extracted from the Silex project. It is a genuinely useful reference for how an adapter is shaped — authentication commands, load, save — but its own listing notes that it targets an older Directus SDK, so treat it as a starting point to read rather than a supported product to drop in.

Directus Storage
Content model

Your CMS. Your content model.

A visual editor is only useful in a headless setup if what it produces still fits the schema you designed. In GrapesJS, a custom component type declares its own editable traits — and those traits are where your CMS field names go.

  1. GrapesJS component
  2. Visual block
  3. Your content schema
  4. CMS

Worked example

hero-section

FieldType
  • titlestring
  • subtitletext
  • imagemedia
  • buttonobject
  • metadatajson
One component type, the traits an editor sees, and the fields your CMS entry already declares — deliberately the same names.
Declaring the same fields on the componentjavascript
editor.DomComponents.addType('hero-section', {
  model: {
    defaults: {
      // Traits become the fields your CMS entry already has.
      traits: [
        { name: 'title',    label: 'Title' },
        { name: 'subtitle', label: 'Subtitle' },
        { name: 'image',    type: 'image' },
        { name: 'ctaHref',  label: 'Button link' },
      ],
    },
  },
});

The visual editor should adapt to your content model — not force your CMS to adapt to the editor.

Storage format

What should you store?

Two representations come out of the same editor, and they answer different questions. One can be reopened for editing; the other can be rendered. Most production setups keep both, in different columns, and that is a design decision rather than a rule.

  • The project document

    1. Project / component data
    2. Editable source
    3. Open later
    editor.getProjectData()

    The component tree, styles, pages and assets as structured data. It is what the editor needs to reconstruct the session exactly as it was left, which is the only representation that survives a second round of editing intact.

    Use it when: someone will open this page in the editor again.

  • The rendered markup

    1. HTML + CSS
    2. Rendered output
    3. Preview / publish
    editor.getHtml() + editor.getCss()

    Markup and stylesheet generated from the same tree. It is what a preview iframe, a static export or a publishing pipeline consumes, and it is not reliably re-importable as an editing session.

    Use it when: something downstream has to render it without the editor.

Store the representation your editor needs for future editing, and generate the output required by your frontend or publishing pipeline.

Editor features

Everything your editors need

What comes with the engine, what a plugin adds, and what stays your application's job. The distinction matters when you are scoping the work rather than reading a feature list.

  • Drag & dropGrapesJS core
  • ComponentsGrapesJS core
  • BlocksGrapesJS core
  • Style managerGrapesJS core
  • Responsive editingGrapesJS core
  • LayersGrapesJS core
  • AssetsPlugin
  • TemplatesPlugin
  • PreviewYour application
Provided byYour applicationGrapesJS corePlugin

GrapesJS ships no CMS, no hosting, no user accounts and no permission model. Those stay with your CMS and your application.

Choosing per content type

CMS editor or page builder?

This is not a decision you make once for the whole product. It is a decision you make per content type, and most teams end up running both.

  • Structured content editor

    Your CMS's own form-based editing, driven by the schema.

    Best for

    • articles
    • text
    • structured fields
    • simple content
  • Visual page builder

    A canvas, where the arrangement is the content.

    Best for

    • landing pages
    • marketing pages
    • custom layouts
    • visual websites
    • complex page composition

Use structured fields where structure matters. Use visual editing where layout and composition matter.

Workflow

Preview content before publishing

Editing and publishing are separate events, and a headless setup makes that easy to enforce: the draft document and the published document are different rows, read by different tokens.

  1. 1

    CMS draft

    The entry exists in your CMS with draft status.

  2. 2

    GrapesJS editor

    Someone composes the page on the canvas.

  3. 3

    Preview

    Your frontend renders the draft at every device width.

  4. 4

    Review

    A second person reads the page as visitors will see it.

  5. 5

    Approve

    The approval is recorded by your application, not by the editor.

  6. 6

    Publish

    Your CMS promotes the draft and your frontend revalidates.

Human gate

What a reviewer should be able to switch between

  • Desktop
  • Tablet
  • Mobile
  • Draft
  • Published

Separate editing from publishing.

Multi-channel

Create once. Deliver everywhere.

This is the benefit you already bought when you chose a headless CMS, and adding a visual editor does not spend it — as long as what the editor writes stays in the content API rather than in a template.

Headless CMS

One content API, read by every channel

  • Pages
  • Blocks
  • Assets
  • Website

    Next.js

  • Mobile

    React Native

  • Application

    Nuxt

Each channel interprets the same payload with its own renderer.

A headless architecture lets the same content infrastructure serve different frontends.

Multi-tenant

Build a multi-tenant headless CMS editor

If the editor is part of a product rather than an internal tool, every customer organisation needs its own pages, assets and templates — and must never see anyone else's.

Your application

The split is enforced here, on the server

  • Organisation A

    • Pages
    • Assets
    • Templates
    • Permissions
  • Organisation B

    • Pages
    • Assets
    • Templates
    • Permissions
  • Organisation C

    • Pages
    • Assets
    • Templates
    • Permissions
One editor, one content API, separate data per organisation.

GrapesJS provides no multi-tenancy of its own. Tenant isolation, per-tenant branding and publishing rules are your application's responsibility, and every storage call has to be scoped server-side.

White-label

Own the entire editing experience

If your customers use the editor, it should look like part of your product. The panels, the icon set, the block library and the templates are all configurable, and the surrounding application supplies everything the editor does not.

  • Custom logo
  • Custom colours
  • Custom interface
  • Custom blocks
  • Custom templates
  • Roles
  • Permissions

Roles and permissions are on that list because a branded editor needs them — not because the editor provides them. They are enforced by your backend.

Ecosystem

Build your headless CMS editor stack

The engine is one rung of the stack. Below is the whole ladder, with an honest label on each rung: what ships in GrapesJS itself, what you can buy or download on GJS.Market, and what remains your own work.

  1. GrapesJS coreOpen source
  2. CMS integrationYour work
  3. BlocksGJS.Market
  4. TemplatesGJS.Market
  5. AssetsGJS.Market
  6. StorageGJS.Market
  7. FormsGJS.Market
  8. SEOGJS.Market
  9. ExportGJS.Market
  10. PublishingGJS.Market
  11. Permissions & auditYour work

Two rungs are marked as your own work on purpose. The CMS integration is specific to your content model, and the catalogue has no permissions or audit-log plugin — an implementation partner can build both, but no product here will.

Real listings

Plugins that matter for a headless setup

Every listing below was checked against the live catalogue and is published and buyable. Prices are read from the marketplace at build time, so what you see is what the listing says today.

By use case

Choose the right plugin stack

Five starting sets, drawn from the same verified listings. None of them is a bundle you buy in one click — they are the combinations that keep coming up for each kind of product.

Prices come from the live catalogue at build time. Free listings are marked.

Build vs extend

Don't build every CMS feature yourself

Every capability on the ladder above is buildable. The question is which ones are worth your team's time when a maintained extension already exists.

Build everythingExtend with plugins
More developmentFaster implementation
More maintenanceReusable extensions
Build every featureAdd only what you need
Internal toolingReady-made solutions

Start with the visual editor. Add capabilities as your product grows.

Build vs adopt

Build a headless CMS editor from scratch vs GrapesJS

Not a vendor comparison — a scope comparison. Each row is a subsystem a visual editor needs, and the only question is whether your team writes it.

CapabilityFrom scratchGrapesJS
CanvasBuildIncluded
Drag & dropBuildIncluded
ComponentsBuildIncluded
BlocksBuildExtensible
StylingBuildIncluded
Responsive editingBuildIncluded
LayersBuildIncluded
AssetsBuildExtensible
TemplatesBuildExtensible
StorageBuildExtensible
ExportBuildExtensible

"Extensible" means the subsystem exists and has an extension point — the block set, template library, asset backend, storage target and export format are yours to supply, from the catalogue or your own code. Catalogue claims verified 2026-09-03.

Build your CMS product. Don't rebuild the visual editor engine.

Objection

Why not just use my CMS's built-in editor?

Often you should. A built-in editor is already integrated, already permissioned and already familiar, and for structured content it is usually the right answer. A dedicated visual editing layer earns its place when you need things the built-in editor was not built to do:

  • richer visual editing on the page itself
  • custom blocks that match your design system
  • responsive layouts checked at each device width
  • custom components bound to your own content types
  • deeper integration with the rest of your product
  • a white-label interface your customers can use
  • custom review and publishing workflows
  • independence from any one frontend

This is not a claim that built-in editors are inferior. It is a claim that the editing surface and the content infrastructure are separable decisions.

Keep your CMS. Choose your own editing experience.

Implementation

How to build a headless CMS visual editor

  1. 1
    Step 1

    Define your content model

    Decide what the editor is allowed to create, and which existing content types it writes into. This decision constrains every one that follows, so make it before any editor code is written.

  2. 2
    Step 2

    Configure GrapesJS

    Set up the component types, the block library and the style controls your editors get — and, just as importantly, the ones they don't.

  3. 3
    Step 3

    Connect storage

    Persist the project document through REST, GraphQL or your own API, with authentication carried by the session your CMS already issues.

  4. 4
    Step 4

    Build preview

    Render the draft with your real frontend, at a route only an authenticated reviewer can reach. Anything else is a preview of a different site.

  5. 5
    Step 5

    Add publishing

    Connect draft, review and production states to the workflow your CMS already has, and record who approved what in your application.

Quick start

Start building

The smallest editor that talks to a content API. Two endpoints, one autosave policy, and the two calls that give you each representation.

npm install grapesjs
Initialise the editor against your APIjavascript
import grapesjs from 'grapesjs';
import 'grapesjs/dist/css/grapes.min.css';

const editor = grapesjs.init({
  container: '#editor',
  height: '100vh',
  // Load and save the project through your CMS API. Both endpoints are
  // yours: GrapesJS only decides when to call them.
  storageManager: {
    type: 'remote',
    autosave: true,
    stepsBeforeSave: 10,
    options: {
      remote: {
        urlLoad: '/api/cms/pages/home',
        urlStore: '/api/cms/pages/home',
        // Send the session the CMS already issued — never a CMS admin token
        // that reached the browser.
        fetchOptions: (opts) => ({ ...opts, credentials: 'include' }),
      },
    },
  },
});

// The two representations, whenever you need them.
const project = editor.getProjectData();          // re-openable source
const output = { html: editor.getHtml(), css: editor.getCss() };

Send the session your CMS already issued. A CMS admin token that reaches the browser is a CMS admin token your visitors have.

Transport

Connect any API

GrapesJS does not care whether the other end is REST, GraphQL or something your team invented. A storage adapter is a load function and a store function, and everything below is a choice you make inside them.

  1. GrapesJS
  2. Storage adapter
  3. REST / GraphQL
  4. Headless CMS

What the adapter has to cover

  • Load project

    Fetch the stored document for one page and hand it to the editor at start-up.

  • Save project

    Write it back, ideally as an update to a draft rather than to the published entry.

  • Autosave

    Save on a change count or a timer, and make the endpoint tolerate being called often.

  • Assets

    Upload through your media pipeline and return the URL the asset manager should show.

  • Preview

    Expose the draft to your frontend behind a token, and to nobody else.

  • Publish

    A separate, authorised endpoint. Never the same call as a save.

The same adapter, against GraphQLjavascript
// A storage adapter is just two functions, so GraphQL needs no extra plugin.
editor.Storage.add('cms', {
  async load() {
    const res = await gql(`query Page($id: ID!) { page(id: $id) { project } }`);
    return res.page.project;
  },
  async store(data) {
    await gql(`mutation Save($id: ID!, $project: JSON!) {
      updatePage(id: $id, data: { project: $project }) { id }
    }`, { project: data });
  },
});

No GraphQL adapter package is published on GJS.Market — the snippet above is the whole integration, which is why none is needed.

Two functions is the entire contract between a visual editor and a content API.

Production

Production-ready headless CMS editor

The list a team works through between a working prototype and something customers touch. Nothing here is exotic; all of it is skipped at least once.

  • Editor

    • Editor lifecycle: initialise and destroy cleanly on route changes
    • Custom component types registered before any project loads
    • Only the plugins this editor actually uses are bundled
  • Data

    • Project persistence proven against a real API, not a mock
    • Autosave interval tuned, and a visible saved state
    • Revisions kept, so a bad save is recoverable
  • Content

    • Schema validation on the server before anything is written
    • Content model documented and versioned with the component types
    • Structured output regenerated on publish, not cached from the editor
  • Security

    • API authentication on every load, save and upload
    • Authorisation checked server-side for the specific page
    • Upload validation: type, size and destination
    • Tenant isolation enforced in the query, not in the interface
  • Workflow

    • Draft state distinct from published state in the CMS
    • Preview route authenticated and excluded from indexing
    • Review step recorded with who and when
    • Publishing endpoint separate, authorised and auditable
Security

Security considerations

A visual editor is a write path into your content infrastructure, so it inherits every rule that path already had — and adds file uploads and arbitrary markup to the surface.

  • Authorise on the server

    Every load, save, upload and publish is checked against the session, for that specific page, on the server.

  • Isolate tenants in the query

    Scope by tenant in the database query itself. A filter applied after the read is not isolation.

  • Authenticate the API

    The editor uses the session your CMS issued. No management or admin token belongs in browser code.

  • Validate uploads

    Check type, size and destination server-side, and serve user media from a separate origin where you can.

  • Sanitise content

    Editors can place custom code. Decide deliberately who may, and sanitise what is rendered to visitors.

  • Protect publishing

    A separate endpoint with its own permission check, so being able to edit is not the same as being able to publish.

Never rely only on client-side permissions. Hiding a panel is a user-interface decision, not a security control.

Performance

Performance considerations

The editor runtime is a developer tool and belongs on the editing route only. Almost every performance problem in this architecture comes from letting it leak into the pages visitors load.

  • Load the editor lazily

    Import it on the editing route. Nothing about a visitor-facing page needs the editing bundle.

  • Page large asset libraries

    A media library grows without limit. Paginate and search it server-side instead of loading it whole.

  • Bundle only the plugins you use

    Each plugin registers components, commands and panels at start-up. Unused ones cost time on every open.

  • Keep the runtime out of published pages

    Published output should be markup and styles rendered by your frontend, with no editor code shipped.

  • Cache API responses deliberately

    The delivery API can be cached hard; the draft read behind preview usually cannot. Treat them separately.

No timings are quoted here because none have been measured for this page. Measure your own editor with your own block set — the block library and asset count dominate the numbers.

FAQ

Headless CMS editor questions

What is a headless CMS editor?

It is the interface people use to create content in a headless CMS — the layer that sits above the content API. In a headless architecture the editing interface is not tied to the frontend, so it can be the CMS's own form-based editor, a visual editor you add, or both for different content types.

What is a headless CMS visual editor?

A visual editor is one where the person editing sees the page while composing it: a canvas, draggable sections, style controls and device widths, instead of a list of fields. It still writes through the content API, so the content stays headless.

Can I use GrapesJS with a headless CMS?

Yes. GrapesJS persists through a storage adapter — a load function and a store function that you point at your API. Any CMS that can return a document and accept an update can back it.

Can I use GrapesJS with Strapi?

There is no official Strapi integration and no Strapi plugin on GJS.Market. The usual approach is a JSON field on a page content type, with the editor's storage adapter calling Strapi's REST or GraphQL API using the caller's session.

Can I use GrapesJS with Contentful?

No official integration exists. Contentful separates its delivery and management APIs, so an integration reads through delivery and writes through management from your server — never with a management token exposed in the browser.

Can I use GrapesJS with Sanity?

No official integration exists. Sanity's document store can hold the editor's project document alongside your existing fields, with the adapter reading and patching that document through Sanity's API.

Can I use GrapesJS with Directus?

Directus is the one platform with a community storage plugin published on GJS.Market. It is free and useful as a reference, but its own listing notes it targets an older Directus SDK, so plan to update or rewrite parts of it.

Can I use GrapesJS with Payload?

No official integration exists. Payload's collections are defined in code, so the field the editor writes into can be declared in the same repository as the editor, which makes the adapter unusually short.

Can I connect a custom CMS?

Yes, and it is often the simplest case. If your backend can answer a load request and accept a save request for one document, it can back the editor. Nothing about the editor assumes a particular product.

Can I use REST APIs?

Yes. The built-in remote storage takes a load URL and a store URL plus your fetch options, so a REST integration can be configuration rather than code.

Can I use GraphQL?

Yes. Register a custom storage adapter whose load runs a query and whose store runs a mutation. No GraphQL-specific plugin is needed, and none is published on GJS.Market.

Can I store GrapesJS projects as JSON?

Yes — the project document is structured data, and a JSON column or field is where it usually goes. That is the representation to keep if the page will be reopened in the editor.

Can I generate HTML and CSS?

Yes. The editor exposes the rendered markup and stylesheet from the same component tree, which is what a preview iframe, a static export or a publishing pipeline consumes.

Should I store HTML or project data?

Store the project data if the page will be edited again, because it is the only representation that reconstructs the session faithfully. Generate the markup for rendering and publishing. Many production setups keep both, in separate fields.

Can I create custom blocks?

Yes. Blocks are registered through the block manager, and a block can insert any component type you have defined — including one bound to your own content schema.

Can I map blocks to my CMS schema?

Yes. Define a component type whose traits use your CMS field names, then have the adapter read those traits into an entry. Keeping the names identical on both sides is what keeps the mapping trivial.

Can I build a visual landing page builder?

Yes, and it is the most common first use case. A campaign page is where structured fields are weakest and a canvas is strongest.

Can I build a multi-tenant CMS editor?

Yes, but the tenancy is your application's, not the editor's. GrapesJS has no concept of a tenant; every storage and asset call has to be scoped on the server.

Can I build a SaaS page builder?

Yes. That means adding accounts, plans, limits and publishing on top of the editor — all of which live in your product rather than in the editing engine.

Can I create a white-label editor?

Yes. Panels, icons, styling, the block library and the templates are all configurable, so the editor can be made to read as part of your own product.

Can I add my own asset management?

Yes. The asset manager has an upload hook, so it can be pointed at your media pipeline or CDN. Plugins exist for common hosted uploaders.

Can I create draft and publish workflows?

Yes, using the states your CMS already has. Keep publishing behind a separate authorised endpoint so that being able to edit does not imply being able to publish.

Can I extend the editor with plugins?

Yes. Plugins add components, blocks, commands, panels and storage targets. The GJS.Market catalogue covers blocks, templates, assets, storage, forms, SEO, export and publishing; permissions and audit logging are not covered and remain custom work.

Services

Need help building your headless CMS editor?

Need help integrating GrapesJS with Strapi, Contentful, Sanity, Directus, Payload or a custom CMS? Get help with editor integration, custom components, storage, plugins and production workflows.

  • Editor integration
  • Custom components
  • Storage adapters
  • Plugin configuration
  • Production workflows
Next step

Give your headless CMS the editing experience it deserves

Keep your existing CMS, content model and frontend architecture. Add GrapesJS as the visual editing layer, then extend it with GJS.Market plugins as your product grows.

Start here

Build your headless CMS editor

Tell us the CMS, the content model and the pages your team needs to compose, and get a scoped setup back.

Get Started
Extend

Browse plugins

Storage, blocks, templates, assets, forms, SEO, export and publishing — the rungs you do not have to write.

Browse plugins
With help

Get implementation help

Integration, custom components, storage adapters and the production workflow around them.

Get implementation help

Your CMS. Your frontend. Your editor.