How to integrate GrapesJS into an Astro app (complete guide 2026)

Embed GrapesJS in an Astro site: mount it in a client-side script, save content to an Astro API endpoint, and export clean HTML/CSS.

DevFuture Development
DevFuture Development
Jun 22, 2026 β€’ 6 days ago
7 min read8 views

Why GrapesJS fits Astro

Astro ships zero JavaScript by default and lets you opt into client-side code per component. GrapesJS is a browser-only editor, so you load it in a client script and save through an Astro API endpoint. This guide mounts the editor, persists content, and exports HTML/CSS.

1. Mount the editor in a client script

Create src/pages/editor.astro. The <script> runs in the browser, so importing GrapesJS there is safe.

---
// src/pages/editor.astro
---
<link href="https://unpkg.com/grapesjs/dist/css/grapes.min.css" rel="stylesheet" />
<div id="gjs"><h1>Edit me in GrapesJS</h1></div>

<script>
  import grapesjs from 'grapesjs';

  const editor = grapesjs.init({
    container: '#gjs',
    height: '100vh',
    fromElement: true,
    storageManager: {
      type: 'remote',
      stepsBeforeSave: 3,
      options: { remote: { urlStore: '/api/page', urlLoad: '/api/page' } },
    },
  });
</script>

2. Add an Astro API endpoint

Create src/pages/api/page.ts. SSR endpoints export HTTP-method functions.

import type { APIRoute } from 'astro';
import { loadPage, savePage } from '../../lib/store';

export const GET: APIRoute = async () => {
  return new Response(JSON.stringify(await loadPage('home')), {
    headers: { 'Content-Type': 'application/json' },
  });
};

export const POST: APIRoute = async ({ request }) => {
  const data = await request.json();
  await savePage('home', data);   // your DB / KV write
  return new Response(JSON.stringify({ status: 'ok' }));
};

Enable an SSR adapter (output: 'server' or 'hybrid' in astro.config.mjs) so the POST is handled at request time.

3. Export the final markup

const html = editor.getHtml();
const css = editor.getCss();
// Persist or render: `<style>${css}</style>${html}`

Common pitfalls in Astro

Web development workspace with code
A POST endpoint needs an SSR adapter; the canvas only runs client-side.

Astro's zero-JS default is the thing to remember. The editor must run client-side β€” a plain <script> tag or a framework island with client:only; importing GrapesJS in frontmatter (server context) will fail. Saving needs runtime: a fully static build can't accept a POST, so set output: 'server' or 'hybrid' with an SSR adapter before wiring the Storage Manager to /api/page. And keep the editor route out of any prerender list β€” you want it rendered on demand, not frozen at build time.

Prerequisites

You'll need Node.js 18+ and an Astro 4 project. To accept a save at runtime you'll also want an SSR adapter (output: 'server' or 'hybrid'). No Astro-specific GrapesJS package exists β€” the editor runs in the browser via a client script or a framework island, and Astro endpoints handle persistence.

Add custom blocks to the editor

Register draggable blocks with the Block Manager after grapesjs.init inside your client script:

editor.BlockManager.add('hero', {
  label: 'Hero section',
  category: 'Sections',
  content: '<section class="hero"><h1>Headline</h1><p>Copy</p></section>',
});

Pull ready-made block libraries and presets from GJS.Market for a richer set.

Storage deep-dive: a custom adapter

A custom storage adapter posts the project to your Astro API endpoint:

editor.Storage.add('astro-store', {
  async load() {
    const res = await fetch('/api/page');
    return res.ok ? res.json() : {};
  },
  async store(data) {
    await fetch('/api/page', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),
    });
  },
});
// then: storageManager: { type: 'astro-store' }

Keep the editor route out of any prerender list so it's rendered on demand, not frozen at build time.

Performance tips

Astro ships zero JS by default, so the editor's weight is opt-in β€” load it only on the editor route via a client script or client:only island. Code-split heavy plugins. Because the rest of the site stays static, your public pages remain fast even with a heavy editor behind an admin route.

Security considerations

Authenticate and authorise the POST endpoint before writing β€” a static-feeling site still needs a guarded save route. Sanitise stored markup on output if non-admins can edit. Validate the payload size so a large project can't exhaust memory.

Troubleshooting common errors

An import error in frontmatter means you imported GrapesJS in the server context β€” keep it in a client <script> or a client:only island. The POST 404s or fails usually means there's no SSR adapter; switch to output: 'server' or 'hybrid'. An unstyled or blank canvas means the stylesheet didn't load or the container wasn't present.

When to use GrapesJS with Astro

GrapesJS fits when an otherwise static Astro site needs an embedded visual editor behind an admin route β€” a page builder or newsletter composer β€” with your own storage and HTML output. For purely static content edited in markdown, Astro's content collections are simpler; for visual full-page composition, GrapesJS is the stronger, MIT-licensed choice.

Next steps

See the related GrapesJS + Svelte and GrapesJS + React guides, browse the GrapesJS marketplace, or start from the GJS.Market home page.

FAQ

Does GrapesJS work in an Astro island?

Yes β€” use a client-side <script> or a framework island with client:only so GrapesJS runs in the browser.

How do I save GrapesJS content in Astro?

Add an API endpoint in src/pages/api exporting POST and have the Storage Manager post the project JSON to it.

Do I need an adapter for the save endpoint?

Yes β€” handling POST at runtime needs an SSR adapter (output: 'server' or 'hybrid'); a fully static build can't accept writes.

Published Jun 22, 2026
Updated Jun 27, 2026
πŸ”Œ GJS.Market

Looking for GrapesJS plugins?

Over 100 curated plugins, presets, and templates β€” hand-picked for quality and maintained by the community.

Share this postTwitterFacebookLinkedIn
Published via
DevFuture Development
DevFuture Development
Visit shop β†’

More from DevFuture Development

Discover other insightful posts and stay updated with the latest content.

View all posts

Premium plugins from DevFuture Development

Hand-picked paid additions crafted by this creator.

Visit shop β†’