PageKit — der selbst gehostete GrapesJS-Website-Builder, als Quellcode. Early Access sichern

Schritt-für-Schritt-Anleitung

GrapesJS-Tutorial: Baue deinen ersten visuellen Editor

Lerne GrapesJS Schritt für Schritt. Baue deinen ersten visuellen Editor, füge Blöcke und benutzerdefinierte Komponenten hinzu, konfiguriere Stile und Assets, speichere Projekte, exportiere HTML/CSS, installiere Plugins und integriere GrapesJS mit React, Vue, Angular oder Next.js.

  • Open-Source-Editor-Framework
  • Selbsthostbar
  • Erweiterbar mit Plugins
  • Individuelle Komponenten
  • HTML/CSS-Export
  • React / Vue / Angular / vanilla JS

Der GrapesJS-Kern wird unter der BSD-3-Clause-Lizenz veröffentlicht; der offizielle React-Wrapper @grapesjs/react ist MIT. Beide erlauben kommerzielle Nutzung. Jedes untenstehende Beispiel wurde mit GrapesJS 0.23.6 abgeglichen.

Das Ergebnis

Was du bauen wirst

Am Ende dieses Tutorials hast du einen funktionierenden Drag-and-Drop-Visual-Editor, der Seiten erstellen, Komponenten bearbeiten, Stile und Assets verwalten, Projekte speichern und die resultierenden HTML und CSS exportieren kann.

  • Blöcke auf eine Leinwand ziehen
  • Komponenten auswählen und bearbeiten
  • Restyle alles von einem Style Manager
  • Wechsle zwischen Desktop-, Tablet- und Handybreiten
  • Lies das Projekt als JSON zurück
  • Exportiere die Seite als HTML und CSS

Geschätzter Lernweg

Anfänger → Fortgeschritten → Produktion

Wie lange das dauert, hängt ganz davon ab, wie viel von der Produktionsschicht dein Produkt benötigt. Die Schritte 1–6 sind ein Nachmittag; Schritte 7–12 sind die Arbeit.

Die offizielle GrapesJS-Demo öffnen
Voraussetzungen

Bevor du anfängst

Sehr wenig. Wenn du eine Seite von Hand schreiben kannst, kannst du diesem folgen.

Grundlegende HTML und CSS

Du solltest ein Tag, eine Klasse und eine CSS-Eigenschaft erkennen. GrapesJS bearbeitet HTML und CSS – nichts Exotischeres.

Grundlegendes JavaScript

Genug, um ein Objekt-Literal und eine Funktion zu lesen. Jedes Beispiel hier ist reines JavaScript.

Node.js und npm

Nur wenn du von npm installierst. Der CDN-Weg in Schritt 1 benötigt nichts außer einem Texteditor und einem Browser.

Du brauchst keine vorherige GrapesJS-Erfahrung und kein Framework. React, Vue, Angular und Next.js werden in Schritt 11 behandelt, nachdem der Kern klar ist.

Anfänger

1. GrapesJS installieren

GrapesJS ist eine Bibliothek, die du deiner eigenen Anwendung hinzufügst, nicht ein Dienst, für den du dich anmeldest. Es gibt zwei Wege hinein, und der gewählte hat keinen Einfluss auf einen späteren Schritt.

Von npm

Das ist der richtige Weg, wenn du einen Build-Schritt irgendeiner Art hast. Er installiert den Editor und sein Stylesheet in dein Projekt; zur Laufzeit wird nichts von einem Drittanbieter-Host abgerufen.

terminal
npm install grapesjs

Von einem CDN

Keine Build-Tools überhaupt: Zwei Tags in einer HTML-Datei und du hast einen Editor. Perfekt für einen First Look oder einen Prototyp. Für alles, was du versendest, pinne eine exakte Version an, anstatt die neueste Version zu verfolgen.

index.html
<link
  rel="stylesheet"
  href="https://unpkg.com/grapesjs/dist/css/grapes.min.css"
/>
<script src="https://unpkg.com/grapesjs"></script>

<div id="gjs"></div>

<script>
  // The UMD build puts the library on window.grapesjs
  const editor = grapesjs.init({ container: '#gjs' });
</script>

Was du gerade installiert hast

Der Editor-Kern

Die Leinwand, der Komponentenbaum, Drag-and-Drop, Rückgängig/Wiederholen, die Panels und die Manager für Blöcke, Stile, Assets, traits, Ebenen und Speicher.

Ein Stylesheet

grapesjs/dist/css/grapes.min.css – das eigene Chrome des Editors. Ohne es bekommt man einen funktionierenden Editor, der kaputt aussieht.

Keine Blöcke

Der Kern liefert eine leere Blockpalette. Die vertrauten Spalten-/Text-/Bildblöcke stammen aus einem Plugin, was Schritt 3 ist.

Kein Backend

Keine Konten, keine Datenbank, kein Hosting. GrapesJS läuft im Browser und übergibt Daten an deine Anwendung, das ist Schritt 7.

Wo GrapesJS in deiner Anwendung steht

Es handelt sich um eine clientseitige Komponente. Ihre Anwendung authentifiziert den Benutzer, entscheidet, welches Projekt geöffnet wird, mountet den Editor in ein DOM-Element und erhält die Projektdaten zurück, wenn sie gespeichert sind. Alles oberhalb und unterhalb des Editors gehört Ihnen.

Anfänger

2. Baue deinen ersten GrapesJS-Editor

Die kleinste nützliche GrapesJS-Anwendung ist ein leeres Element und ein Aufruf. Kopiert man beide unten unten liegenden Blöcke auf eine Seite, hat man einen funktionierenden Editor.
index.html
<!-- The editor takes over this element completely.
     Do not render anything inside it yourself. -->
<div id="gjs"></div>
Ein Element. GrapesJS ersetzt seinen Inhalt vollständig, also rendere niemals dein eigenes UI darin.
editor.js
import grapesjs from 'grapesjs';
import 'grapesjs/dist/css/grapes.min.css';

const editor = grapesjs.init({
  // Where the editor mounts: a selector or an HTMLElement.
  container: '#gjs',
  height: '100vh',
  width: 'auto',

  // Do not adopt the markup already inside #gjs...
  fromElement: false,
  // ...load this instead. Strings are parsed into components.
  components: `
    <section class="hero">
      <h1>Hello GrapesJS</h1>
      <p>Drag a block from the panel on the right.</p>
    </section>`,
  style: `
    .hero { padding: 64px 32px; font-family: system-ui, sans-serif; }
    .hero h1 { margin: 0 0 12px; font-size: 40px; }`,

  // Storage is ON by default and writes to localStorage.
  // Turn it off until you have decided where projects really live.
  storageManager: false,
});
Zwei Optionen sind hier am ersten Tag erwähnenswert: fromElement entscheidet, ob der Editor das bereits im Container gespeicherte Markup übernimmt, und storageManager setzt standardmäßig auf einen localStorage-gesicherten Speicher, der die Leinwand leise im Browser des Lesers speichert. Das Ausschalten jetzt vermeidet später eine verwirrende Menge an Geisterzustand.

Was jeder Teil bedeutet

Behälter
Das Element, in das der Editor montiert wird – ein CSS-Selektor oder ein HTMLElement. Gib ihm eine echte Höhe an, oder der Editor rendert null Pixel hoch.
Editor-Instanz
Was init() zurückgibt. Jedes API in diesem Tutorial hängt daran, und wenn man destroy() darauf aufruft, werden DOM und die Zuhörer freigegeben.
Leinwand
Das iframe, das deine Seite enthält, wird darin bearbeitet. Da es ein echtes iframe ist, kann das CSS deiner Seite nicht hineinsickern, und das CSS kann auch nicht rauslaufen.
Ursprüngliches Projekt
Womit die Leinwand beginnt – die Komponenten und Stiloptionen oder was auch immer die Speicherschicht lädt.
Konfiguration
Ein einzelnes Objekt. Jeder Manager in den späteren Schritten wird mit einem Schlüssel konfiguriert: blockManager, styleManager, assetManager, storageManager, deviceManager.

Was du sehen solltest

Eine dreiteilige Benutzeroberfläche: die Leinwand in der Mitte, der Panel-Schalter oben rechts und – sobald du in Schritt 3 Blöcke hinzugefügt hast – eine Palette zum Ziehen. Der Editor über diesem Abschnitt ist genau diese Konfiguration mit sechs Blöcken und drei hinzugefügten Gerätebreiten.

Live-Demo öffnen
Anfänger

3. Hinzufügen von Drag-and-Drop-Blöcken

Vor jedem Code gibt es eine Unterscheidung. Das ist das Einzige, was Anfänger am häufigsten falsch machen, und von hier an hängt alles davon ab.

Block

Ein Paletteneintrag. Er existiert nur im Panel und enthält ein Rezept, was erstellt werden soll. Er hat ein Label, eine Kategorie, ein Symbol und Inhalte.

Komponente

Ein Knoten in der Leinwand. Er hat einen Typ, Attribute, Stile, Kinder, und das ist es, was exportiert und gespeichert wird.

Ein Block ist das, was der Benutzer in die Leinwand zieht. Sobald der Block abgeworfen wurde, erstellt er Komponenten im Editor. Ein Block kann einen ganzen Teilbaum von Komponenten bilden – und derselbe Block, der zweimal abgeworfen wird, erzeugt zwei unabhängige Unterbäume.

Eine Starterpalette

  • Hero
  • Bild
  • Text
  • Button
  • Zwei Spalten
  • Kontaktformular
blocks.js
// A Block is a palette entry. Dropping it creates Components.
editor.Blocks.add('hero-section', {
  label: 'Hero',
  category: 'Sections',
  // Shown in the palette. Any HTML string works; an inline SVG keeps it sharp.
  media: '<svg viewBox="0 0 24 24" width="22"><rect x="3" y="5" width="18" height="6" rx="1" fill="currentColor"/><rect x="3" y="13" width="11" height="3" rx="1" fill="currentColor" opacity=".5"/></svg>',
  content: `
    <section class="hero">
      <h1>Headline</h1>
      <p>Supporting copy.</p>
      <a href="#" class="btn">Call to action</a>
    </section>`,
});

// The same block, expressed as a component definition instead of HTML.
// Use this form once you have your own component types (step 10).
editor.Blocks.add('product-card', {
  label: 'Product card',
  category: 'Commerce',
  content: { type: 'product-card' },
});
Content akzeptiert entweder eine HTML-Zeichenkette oder eine Komponentendefinition. Zeichenketten sind der schnellste Weg zum Einstieg; die Objektform ist das, worauf du wechselst, sobald du in Schritt 10 deine eigenen Komponententypen hast.

Die Kernschiffe haben keine Blockade

Das überrascht fast alle. Ein standardmäßiger GrapesJS-Editor hat eine leere Palette – das bekannte Set "1 Spalte / 2 Spalten / Text / Bild", das in jedem Screenshot erscheint, stammt aus grapesjs-blocks-basic oder einem der Presets. Entweder schreibst du deine eigenen Blöcke, wie oben, oder fügst ein Preset hinzu.

blocks-preset.js
import grapesjs, { usePlugin } from 'grapesjs';
import blocksBasic from 'grapesjs-blocks-basic';

// The core ships no blocks at all. The familiar
// "1 column / 2 columns / text / image" palette is a plugin.
grapesjs.init({
  container: '#gjs',
  plugins: [usePlugin(blocksBasic, { flexGrid: true })],
});
usePlugin() ist die aktuelle Methode, ein Plugin zu registrieren. Ältere Tutorials nennen grapesjs.plugins.add(); dass API veraltet ist und eine Warnung meldet.
Anfänger

4. GrapesJS-Komponenten verstehen

Die Leinwand ist kein HTML-String, den GrapesJS beim Speicherstand parst. Es handelt sich um einen Live-Baum von Komponentenmodellen, und der HTML wird aus diesem Baum generiert. Sobald das klickt, hört der Rest des API auf, überraschend zu sein.

Der Wortschatz

Komponentenbaum
Jeder Knoten in der Leinwand ist eine Komponente, und jede Komponente hat einen Elternteil und Kinder. Die Wurzel ist der Wrapper.
Bauteiltypen
Eingebaute Typen umfassen Text, Bild, Link, Video, Tabelle und eine generische Standardeinstellung. Ein Typ entscheidet, wie sich ein Knoten verhält, rendert und exportiert.
Verschachtelte Komponenten
Eindämmung ist eine echte Beziehung, keine Vertiefung. droppable und draggable bestimmen, was in was gelangen darf.
Eigenschaften
HTML-Attribute — class, href, id, data-*. Sie werden wortwörtlich im exportierten Markup veröffentlicht.
Eigenschaften
Modellzustand, der kein HTML-Attribut ist. Nützlich für alles, was der Editor sich merken muss, aber die Seite sollte nicht tragen.
Merkmale
Das Einstellungsfeld für die ausgewählte Komponente. Ein Merkmal bearbeitet standardmäßig ein Attribut oder eine Eigenschaft, wenn du changeProp einstellst.

Ein typischer Teilbaum

  • wrapper, Tiefe 0
  • Section, Tiefe 1
  • Container, Tiefe 2
  • Heading, Tiefe 3
  • Button, Tiefe 3
Der Layer Manager zeigt genau das. Wenn man einen Knoten auf der Leinwand auswählt, wird er im Baum ausgewählt, und umgekehrt.
components.js
// Every node in the canvas is a Component, and the canvas is a tree.
const wrapper = editor.getWrapper();

wrapper.components().forEach((component) => {
  console.log(
    component.get('type'),      // 'text' | 'image' | 'link' | your own type
    component.getName(),        // label shown in the Layer manager
    component.components().length // number of children
  );
});

// React to what the user selects — the hook most custom UI hangs off.
editor.on('component:selected', (component) => {
  console.log('selected', component.getId(), component.get('type'));
});
getWrapper() ist die Wurzel des Baums. Von dort aus liefert components() die Kinder eines beliebigen Knotens – so läuft jedes benutzerdefinierte Panel, jeder Exporter und jeder Validator in einem Produktionseditor über das Dokument.
cta-button.js
// Traits are the settings panel for a component.
// By default a trait writes an HTML attribute.
editor.Components.addType('cta-button', {
  extend: 'link',
  model: {
    defaults: {
      name: 'CTA button',
      attributes: { class: 'btn' },
      components: 'Call to action',
      traits: [
        { name: 'href', label: 'Link' },
        { name: 'title', label: 'Title' },
        {
          type: 'select',
          name: 'target',
          label: 'Opens in',
          options: [
            { id: '', name: 'Same tab' },
            { id: '_blank', name: 'New tab' },
          ],
        },
      ],
    },
  },
});
extend erbt alles von einem bestehenden Typ und überschreibt nur das, was du nennst. Es ist fast immer der richtige Ausgangspunkt: ein Link, der sich wie ein Link verhält, mit deinem eigenen traits obendrauf.
Anfänger

5. Den Style Manager konfigurieren

Der Style Manager schreibt CSS-Regeln für alles, was ausgewählt wird. Bleibt es auf den Standardeinstellungen, bietet es jedem, der deinen Editor benutzt, einen großen Teil von CSS an – was für ein Entwickler-Tool in Ordnung ist und für fast jedes Produkt falsch ist.

Sektoren und was normalerweise in ihnen hineingeht.

Typografie
Schriftfamilie, Schriftgröße, Schriftstärke, Linienhöhe, Farbe, Ausrichtung.
Abstand
Margin und Füllmaterial sind meist die beiden Eigenschaften, die die Autoren tatsächlich anstreben.
Dimension
Breite, Max-Breite, Höhe und ihre Min/Max-Varianten.
Auszeichnungen
Hintergrundfarbe und Bilder, Grenzradius, Grenzen, Schatten.
Responsive
Styles werden pro Gerät geschrieben. Wechselt man die Leinwand auf Tablet oder Handy, schreibt dieselbe Steuerung stattdessen in eine Medienanfrage.
Benutzerdefinierte Eigenschaften
Du kannst deine eigenen Eigenschaftstypen definieren – einen Token-Picker, eine Abstandsskala – anstatt rohes CSS offenzulegen.
style-manager.js
grapesjs.init({
  container: '#gjs',
  styleManager: {
    // Sectors are the collapsible groups in the right-hand panel.
    // Listing them yourself is how you stop the editor offering
    // 100+ CSS properties to a non-technical author.
    sectors: [
      {
        id: 'typography',
        name: 'Typography',
        open: true,
        properties: [
          'font-family',
          'font-size',
          'font-weight',
          'line-height',
          'color',
          'text-align',
        ],
      },
      { id: 'spacing', name: 'Spacing', properties: ['margin', 'padding'] },
      {
        id: 'dimension',
        name: 'Dimension',
        properties: ['width', 'max-width', 'height'],
      },
      {
        id: 'decorations',
        name: 'Decorations',
        properties: ['background-color', 'border-radius', 'border', 'box-shadow'],
      },
    ],
  },
});
Sektoren sind die zusammenklappbaren Gruppen im rechten Panel. Sie explizit zu benennen ist der Weg, "ganz CSS" in eine kurze, bewusste Auswahl zu verwandeln.

Struktur und Styling sind unterschiedliche Fragen

Komponentenstruktur

Was existiert, was was enthält, was kann hinzugefügt oder entfernt werden. Kontrolliert mit dem Bauteiltyp droppable, draggable und removable.

Bauteilgestaltung

Wie ein Bauteil aussehen kann. Gesteuert mit der Style Manager-Konfiguration und mit stylable / unstylable am Bauteil selbst.

restricted-heading.js
// Structure and styling are separate concerns. A component can accept
// children while refusing to be restyled beyond a fixed allowance.
editor.Components.addType('brand-heading', {
  extend: 'text',
  model: {
    defaults: {
      name: 'Brand heading',
      // Only these properties reach the Style manager for this component.
      stylable: ['color', 'text-align'],
      // Everything else stays on the class in your own stylesheet.
      attributes: { class: 'brand-h2' },
    },
  },
});
Eine Komponente kann Kinder aufnehmen und sich weigert, neu gestaltet zu werden. Diese Kombination – offene Struktur, geschlossenes Styling – ist das, woraus ein Design-System-Editor besteht.
Anfänger

6. Bilder und Assets verwalten

Das Asset Manager ist das Modal, das sich öffnet, wenn ein Leser ein Bild doppelklickt. Es listet Assets auf, akzeptiert Uploads und gibt eine URL an die ausgewählte Komponente zurück.

Was es abdeckt

Bildhochladungen
Drag-and-Drop oder Datei-Picker, der auf einen von dir gewählten Endpunkt postet wird.
Bild-URLs
Leser können eine URL für alles, was du bereits hostest, einfügen.
Asset-Auswahl
Ein Doppelklick auf eine Bildkomponente öffnet das Panel und schreibt das gewählte src zurück.
Individuelle Anbieter
Ersetze den Upload komplett durch uploadFile und sprich mit dem Speicher, den du nutzt.
Externer Speicher
S3, R2, Cloudinary, ein internes DAM – GrapesJS muss nie wissen, wo sich die Bytes befinden, nur die URL.
asset-manager.js
grapesjs.init({
  container: '#gjs',
  assetManager: {
    // Seed the panel with images you already host.
    assets: [
      'https://cdn.example.com/hero.jpg',
      { src: 'https://cdn.example.com/team.jpg', name: 'Team', category: 'People' },
    ],
    // Your upload endpoint. Set `upload: false` to disable uploading entirely.
    upload: 'https://api.example.com/uploads',
    uploadName: 'files',
    headers: { Authorization: 'Bearer <token>' },
    multiUpload: true,
    // Add the response's assets to the panel automatically. Your endpoint must
    // answer with { data: [ ...assets ] }.
    autoAdd: true,
  },
});
Upload ist der schnellste Weg: Zeigen Sie es auf einen Endpunkt, der mit { data: [ ... ] } antwortet, und setzen Sie autoAdd. Headers sind der Ort, an den Ihr Auth-Token gehört.
asset-upload.js
// Full control: upload wherever you like, then hand the URLs back.
grapesjs.init({
  container: '#gjs',
  assetManager: {
    async uploadFile(event) {
      const files = event.dataTransfer
        ? event.dataTransfer.files
        : event.target.files;

      const urls = await uploadToYourStorage(files); // S3, R2, Cloudinary…
      editor.AssetManager.add(urls);
    },
  },
});

// Without `upload` or `uploadFile`, dropped images are embedded as base64
// straight into the project — convenient in a demo, painful in production.
uploadFile gibt dir die Rohdateien und macht sich aus dem Weg. Das ist die Version, die die meisten Produktionseditoren verwenden, da Uploads meist signiert, verkleinert oder ein Tenant-Präfix benötigen.

Eine Sache, die man früh entscheiden sollte

Da weder Upload noch uploadFile konfiguriert sind, integriert GrapesJS abgegebene Bilder als base64 ins Projekt. Es funktioniert sofort und bläht das gespeicherte Projekt so lange auf, bis es langsam lädt und teuer im Übertragen wird. Verbinde Asset Manager mit echtem Speicher, bevor jemand anfängt, Inhalte zu produzieren.

Fortgeschritten

7. GrapesJS-Projekte speichern und laden

Das Storage Manager entscheidet, wohin das editierbare Projekt geht. Es ist standardmäßig aktiviert und schreibt in localStorage – weshalb ein gestern erstellter Editor immer noch die Leinwand von gestern enthält.

Was es dir gibt.

Projekt JSON
Das gesamte editierbare Dokument – Komponenten, Stile, Seiten, Assets – als einfaches, serialisierbares Objekt.
Autosave
Speichere nach einer festgelegten Anzahl von Bearbeitungen statt bei jedem Tastendruck mit stepsBeforeSave.
Last
Hol dir ein Projekt auf init oder ruf loadProjectData() selbst an, wann immer du möchtest.
Speichern
Ausgelöst durch autosave oder durch editor.store() über deinen eigenen Werkzeugleisten-Button.
Fernspeicherung
Ein integrierter Fetch-basierter Store: Gib ihm eine Lade-URL, eine Store-URL, Header und Anfrage-/Antwort-Adapter.
Individuelle Speicherung
Registrieren Sie Ihr eigenes Load/Store-Paar für GraphQL, einen Offline-Cache oder alles, was Remote nicht abdeckt.
storage-manager.js
grapesjs.init({
  container: '#gjs',
  storageManager: {
    type: 'remote',
    autosave: true,
    autoload: true,
    // Batch changes: save after N edits rather than after every keystroke.
    stepsBeforeSave: 5,
    options: {
      remote: {
        urlLoad: '/api/projects/42',
        urlStore: '/api/projects/42',
        headers: { 'X-CSRF-Token': csrfToken },
        credentials: 'include',
        // Shape the request body to match your API…
        onStore: (data) => ({ project: data }),
        // …and pull the project back out of your response.
        onLoad: (result) => result.project,
      },
    },
  },
});
onStore und onLoad sind die beiden Hooks, die in einem echten API entscheiden: Sie lassen die Nutzlast des Editors und den Vertrag deines Endpunkts unterschiedlich sein, ohne dass eine Seite Kompromisse eingeht.
custom-storage.js
// When `remote` does not fit — GraphQL, a queue, an offline-first cache —
// register a storage of your own and select it by name.
editor.Storage.add('my-api', {
  async load() {
    const res = await fetch('/api/projects/42');
    const { project } = await res.json();
    return project; // the object you previously stored
  },
  async store(data) {
    await fetch('/api/projects/42', {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ project: data }),
    });
  },
});

// storageManager: { type: 'my-api' }

// You can also drive it by hand, with no storage configured at all:
const project = editor.getProjectData();   // plain JSON — store it anywhere
editor.loadProjectData(project);           // and put it back
Oder überspringe Storage Manager komplett. getProjectData() gibt einfaches JSON zurück und loadProjectData() setzt es wieder ein – viele Produktionseditoren machen genau das und erzeugen das Speichern aus ihrem eigenen Anwendungszustand.

Wo GrapesJS endet.

GrapesJS stellt den Editor und die Projektdatenschicht bereit, aber Ihre Anwendung entscheidet, wo Produktionsdaten gespeichert werden. Welcher Benutzer ein Projekt besitzt, zu welchem Tenant es gehört, wer es öffnen darf, wie viele Revisionen Sie speichern, wann es gesichert wird – nichts davon befindet sich in der Bibliothek und sollte es auch nicht sein.

Fortgeschritten

8. HTML und CSS exportieren

Zwei Aufrufe verwandeln die Leinwand in eine Seite. Das sind die Aufrufe, an die die HTML- und CSS-Knöpfe im Live-Editor oben angeschlossen sind.
export.js
const html = editor.getHtml();
const css = editor.getCss();

// Two things surprise everyone on their first export:
//
// 1. getHtml() returns the canvas wrapped in <body> … </body>.
//    Strip or template around it before you save a fragment.
// 2. getCss() includes GrapesJS's own canvas reset unless you opt out:
const pageCss = editor.getCss({ avoidProtected: true });

// Export one branch instead of the whole page:
const selected = editor.getSelected();
const partial = editor.getHtml({ component: selected });

// The editable project — NOT the same thing as the exported page.
const project = editor.getProjectData();
getHtml() und getCss() lesen das aktuelle Dokument. Keiner berührt den Speicher, und keiner davon beeinflusst, ob du einen solchen Dokument konfiguriert hast.

Zwei Dinge, die alle überraschen

getHtml() wickelt in <body>

Die Wrapper-Komponente wird als Body-Element exportiert. Wenn du ein Fragment speicherst, eine Vorlage darum herum oder es abstrippen – geh nicht davon aus, dass du einen nackten Abschnitt zurückbekommst.

getCss() enthält den Reset des Editors

GrapesJS liefert ein kleines, geschütztes Stylesheet für die Leinwand. Passen Sie avoidProtected: True, wenn Sie nur das CSS wollen, das Ihr Reader tatsächlich erstellt hat.

Eine typische Verlagspipeline

  1. GrapesJS
  2. HTML + CSS
  3. Your API
  4. Storage / CMS
  5. Published page
Die genaue Pipeline ist anwendungsspezifisch – einige Produkte schreiben eine statische Datei, andere speichern ein gerendertes Dokument neben dem Projekt, manche rendern bei jeder Anfrage serverseitig vom Projekt JSON. Der Teil von GrapesJS endet mit dem ersten Pfeil.

Zwei Ausgaben, zwei Arbeitsplätze

getHtml() und getCss() zeigen dir, was Besucher sehen. getProjectData() gibt dir das, was der Autor weiter bearbeiten kann. Speichere das Projekt; generiere die Seite daraus neu. Wenn du nur HTML speicherst, beginnt die nächste Bearbeitung mit geparstem Markup und nicht aus dem Dokument, das der Autor erstellt hat.

Fortgeschritten

9. GrapesJS mit Plugins erweitern

Plugins sind eine der Hauptmöglichkeiten, GrapesJS über den Kerneditor hinaus zu erweitern. Ein Plugin ist nichts weiter als eine Funktion, die die Editor-Instanz empfängt – alles, was du in deinem eigenen Setup-Code machen kannst, kann ein Plugin auch.
plugins.js
import grapesjs, { usePlugin } from 'grapesjs';
import blocksBasic from 'grapesjs-blocks-basic';
import forms from 'grapesjs-plugin-forms';

grapesjs.init({
  container: '#gjs',
  plugins: [
    usePlugin(blocksBasic, { flexGrid: true }),
    usePlugin(forms, {}),
  ],
});
usePlugin() registriert ein Plugin mit seinen Optionen. Ältere Tutorials zeigen grapesjs.plugins.add(); dass API in aktuellen Versionen veraltet ist und eine Warnung vermerkt, dass man stattdessen dieses verwenden soll.
my-plugin.js
// A plugin is just a function that receives the editor.
// Anything you can do at init you can do inside one.
export default function dividerPlugin(editor, options = {}) {
  const category = options.category ?? 'Basic';

  editor.Blocks.add('divider', {
    label: 'Divider',
    category,
    content: '<hr class="divider" />',
  });

  editor.Commands.add('clear-canvas', {
    run: (ed) => ed.Components.clear(),
  });
}

// Then: plugins: [usePlugin(dividerPlugin, { category: 'Layout' })]
Das Schreiben eines Editors ist dieselbe Arbeit wie das Konfigurieren des Editors, aber in eine Datei verschoben, die man projektübergreifend wiederverwenden kann. Blöcke, Komponententypen, Befehle, Panels, traits und Stilsektoren können alle von innen registriert werden.

Oder einen installieren

Benötigen Sie Funktionen, die in Ihrem Basis-Editor nicht enthalten sind? Entdecken Sie Plugins und Erweiterungen, die über GJS.Market verfügbar sind. Unten finden Sie echte Einträge aus dem Katalog, gruppiert nach dem Schritt, zu dem sie gehören.

Marktplatz

Plugins für die Schritte, die du gerade erledigt hast

Echte Einträge aus dem GJS.Market-Katalog, gruppiert nach dem Teil des Tutorials, den sie erweitern. Hier ersetzt nichts den Kern – jeder füllt eine Naht, die der Kern absichtlich offen lässt.

Profi

10. Eigene Komponenten bauen

Hier hört ein GrapesJS-Editor auf, ein generischer HTML-Editor zu sein, und wird Teil deines Produkts. Ein benutzerdefinierter Komponententyp ist eine benannte Sache, die deine Autoren platzieren können, mit eigener Struktur, eigenen Einstellungen und eigenen Regeln darüber, was geändert werden darf.

Was in einen Bauteiltyp einfließt

Der Typ
Ein Name, den man mit Components.addType registriert, wobei optional ein eingebauter Typ erweitert wird.
Das Modell
Standardwerte, Kinder, Attribute, Eigenschaften und die Schlösser – droppable, draggable, removable, stylable.
Merkmale
Die Einstellungen, die dein Autor tatsächlich sieht. changeProp schreibt auf das Modell statt auf ein Attribut.
Die Aussicht
Optional. Rendering überschreiben, wenn die Leinwand etwas anderes als das exportierte Markup anzeigen muss.
isComponent
Wie GrapesJS deinen Typ erkennt, wenn es gespeichertes HTML wieder in den Baum einführt.
A-Block
Der Paletteneintrag, der ihn erstellt, mit Inhalt: { type: 'your-type' }.

Eine Produktkarte als Komponententyp

  • Product Card, Tiefe 0
  • Image, Tiefe 1
  • Product Name, Tiefe 1
  • Price, Tiefe 1
  • CTA, Tiefe 1
Der Autor bearbeitet das Bild, den Namen, den Preis und den Button. Er kann den Preis nicht löschen, die Teile nicht neu bestellen oder die Karte in etwas anderes verwandeln – denn droppable ist falsch und die Kinder sind fixiert.
product-card.js
editor.Components.addType('product-card', {
  // Lets GrapesJS recognise the type when parsing saved HTML.
  isComponent: (el) => el.dataset?.gjsType === 'product-card',

  model: {
    defaults: {
      name: 'Product card',
      attributes: { 'data-gjs-type': 'product-card', class: 'product-card' },

      // Author-visible settings. `changeProp` writes to the model
      // instead of to an HTML attribute.
      traits: [
        { name: 'sku', label: 'SKU', changeProp: true },
        {
          type: 'checkbox',
          name: 'showPrice',
          label: 'Show price',
          changeProp: true,
        },
      ],
      sku: '',
      showPrice: true,

      // Fixed structure: the author edits the parts, not the layout.
      components: [
        { type: 'image', attributes: { class: 'product-card__image' } },
        { type: 'text', name: 'Name', components: 'Product name' },
        { type: 'text', name: 'Price', attributes: { class: 'product-card__price' }, components: '$0.00' },
        { type: 'cta-button', components: 'Add to cart' },
      ],

      // Locks that make the card a card and not a free-form div.
      droppable: false,
      stylable: ['background-color', 'border-radius', 'box-shadow'],
    },

    init() {
      this.on('change:showPrice', this.togglePrice);
    },

    togglePrice() {
      const price = this.components().at(2);
      price?.addStyle({ display: this.get('showPrice') ? 'block' : 'none' });
    },
  },
});
Die Schlösser am unteren Rand sind die interessante Hälfte. droppable: false verhindert, dass die Karte ein Container wird; stylable beschränkt das Restyling auf drei Eigenschaften; das traits gibt dem Autor genau zwei Entscheidungen.

Warum das für ein Produkt wichtig ist

Eine SaaS-Anwendung kann produktspezifische Komponenten offenlegen – eine Preistabelle, die mit echten Plänen verbunden ist, eine Produktkarte, die an eine SKU gebunden ist, ein Buchungs-Widget – statt eines generischen uneingeschränkten HTML-Editors. Autoren haben weniger Auswahl und bessere Ergebnisse, und Ihre Support-Warteschlange sieht nie eine Seite, die jemand mit einem verirrten Float kaputt gemacht hat.

Zusammensetzen

Baue einen kontrollierten Editor mit deinem Designsystem

Die Schritte 3, 5 und 10 ergeben das Nützlichste, was du mit GrapesJS tun kannst: Ersetze "alles ist möglich" durch "diese sieben Dinge, richtig gemacht". Jeder Mechanismus ist einer, den du bereits kennengelernt hast.

Benutzerdefinierte Blöcke

Die Palette ist das Menü. Wenn sie nicht im Regal steht, kann sie niemand hinzufügen.

Individuelle Komponenten

Feste Struktur pro Block, wobei die Teile, die bearbeitbar sein sollten, als bearbeitbar markiert sind.

Merkmale

Die Einstellungen, die ein Autor erhält – eine Überschrift, ein Link, eine Variante – statt rohes Markup.

Style Manager-Konfiguration

Sektoren, die nur die Eigenschaften auflisten, die dein System tatsächlich erlaubt.

Erlaubte Stile

stylable und unstylable pro Komponente, sodass eine Karte die Farbe wechseln kann, aber kein Float wird.

Wiederverwendbare Bauteile

Geteilte Stücke, die synchron bleiben, anstatt pro Seite kopiert zu werden.

Vorlagen

Ein Startdokument pro Seitentyp, sodass niemand mit einer leeren Leinwand beginnt.

Custom UI

Die Panels von GrapesJS sind austauschbar. Ein Produkteditor sieht selten wie der Standard-Editor aus.

Dein SaaS-Designsystem

  • Hero
  • Feature Grid
  • Pricing
  • Testimonials
  • FAQ
  • CTA
  • Footer
Sieben Blöcke, jeder unterstützt von einem Komponententyp, den du kontrollierst. Ein Autor wählt aus diesem Regal und kann keine Seite produzieren, die nicht zum Markenzeichen passt, weil es nichts Off-Brand gibt, das man auswählen könnte.

Verwandle GrapesJS von einem generischen Editor in einen speziell für dein Produkt entwickelten Editor.

Zwei Leitfäden gehen in zwei Richtungen weiter:

Integration

GrapesJS mit deinem Framework verwenden

GrapesJS rendert in ein einfaches DOM-Element, sodass die "Integration in ein Framework" auf eine Frage hinausläuft: Welcher Lebenszyklus-Hook ruft init() auf und welcher auf destroy(). Das folgende Muster ist React; die speziellen Guides decken den Rest ab, einschließlich der Teile, die wirklich framework-spezifisch sind.

Editor.tsx
import { useEffect, useRef } from 'react';
import grapesjs, { type Editor } from 'grapesjs';

export function GjsEditor() {
  const ref = useRef<HTMLDivElement>(null);
  const editorRef = useRef<Editor | null>(null);

  useEffect(() => {
    if (!ref.current) return;
    editorRef.current = grapesjs.init({
      container: ref.current,
      height: '100vh',
      storageManager: false,
    });
    // GrapesJS owns this node now — React must never render into it again.
    return () => {
      editorRef.current?.destroy();
      editorRef.current = null;
    };
  }, []);

  return <div ref={ref} />;
}
Die zwei Regeln, die jedes Framework überleben: Initialisieren Sie einmal und lassen Sie das Framework danach nie wieder in den Container rendern. GrapesJS besitzt diesen Knoten.

Ein Hinweis, der alle auf einem server-gerenderten Framework trifft: GrapesJS berührt das Fenster, wenn das Modul geladen wird, sodass der Editor nur auf dem Client importiert werden muss. Der Next.js-Guide behandelt genau das.

Architektur

Vom Tutorial zur Produktion

Ein Produktionseditor benötigt in der Regel mehr als grapesjs.init(). Nicht, weil die Bibliothek unvollständig ist – sondern weil ein Editor eine Produktschicht ist und die umliegenden Schichten deine.

Ein typischer Produktionsstack

  1. Your application
  2. Authentication
  3. GrapesJS editor
  4. Custom components / blocks
  5. Storage API
  6. Database / CMS
  7. Asset storage
  8. Publishing
GrapesJS nimmt ein Band dieses Diagramms ein. Alles darüber und darunter ist Anwendungscode, den du schreibst, kaufst oder bereits besitzt.

Was die umliegenden Schichten zu beantworten haben

Authentifizierung
Wer überarbeitet, und wie beweist der Storage-Call des Editors das?
Berechtigungen
Wer darf welche Seite bearbeiten und wer darf sie veröffentlichen?
Projekteigentum
Zu welchem Nutzer oder Team ein Projekt gehört und was passiert, wenn sie gehen.
Mehrfach-Mietverhältnisse
Die Projekte, Assets und Vorlagen eines Kunden von denen eines anderen fernzuhalten.
Autosave
Wie oft, was bei einem fehlgeschlagenen Spielstand passiert und was der Leser sieht, wenn er fehlschlägt.
Vorlagen
Wo startet eine neue Seite und wie eine Änderung an Vorlagen bereits erstellte Seiten erreicht.
Asset-Speicherung
Wo Uploads hingehören, wie sie benannt werden und wer sie abholen darf.
Verlagswesen
Wie die exportierten HTML und CSS zu einer Seite werden, die ein Besucher laden kann.
Fehlerbehandlung
Ein Spielstand, der lautlos fehlschlägt, ist der schlimmste Bug, den ein Editor haben kann.
Backups
Projekt JSON ist klein und lässt sich gut komprimieren. Es gibt keine Entschuldigung, es zu verlieren.
Sicherheit
Benutzerdefinierte Codeblöcke und eingefügte HTML sind Benutzereingaben. Desinfizieren Sie auf dem Weg nach draußen.
Leistung
Große Projekte, große Asset-Listen und lange Undo-Stacks haben alle Kosten, die es wert sind, gemessen zu werden.
Versionierung
Überarbeitungen, Entwürfe und die Möglichkeit, eine Seite zurückzudrehen, die jemand kaputt gemacht hat.
Die Trennlinie

GrapesJS-Aufgaben im Vergleich zu den Zuständigkeiten deiner Anwendung

Nichts weiter unten ist eine Kritik an GrapesJS – es ist ein Editor-Framework, und hier sollte es aufhören. Die Zeile vor Beginn zu kennen, verhindert, dass ein dreiwöchiger Build zu einem neunmonatigen wird.

Deine Anwendung
  • AuthentifizierungNicht in der Bibliothek, absichtlich.
  • Rollen und BerechtigungenWer redigieren darf, wer veröffentlichen darf.
  • ProjekteigentumBenutzer, Teams, Übertragung, Löschung.
  • Mehrfach-MietverhältnisseIsolation zwischen Kunden.
  • VersionierungEntwürfe, Überarbeitungen, Rollback.
  • VerlagswesenEinen Export in eine Live-Seite umwandeln.
  • BackupsRetention und Wiederherstellung.
  • Hosting und DomainsDNS, Zertifikate, Zustellung.
GrapesJS-Kern
  • Leinwand bearbeitenDie iframe, Auswahl, Schwebe, Werkzeugleisten.
  • Drag & DropUmziehen, verschachteln und Komponenten neu ordnen.
  • KomponentenbaumTypen, Kinder, Attribute, traits.
  • Style ManagerIch schreibe CSS-Regeln für die Auswahl.
  • Responsive BearbeitungGeräte und Pro-Breakpoint-Stile.
  • Rückgängig machen und neu machenCore-Befehle, standardmäßig auf der Tastatur gebunden.
  • ProjektdatenSerialisierung und Wiederherstellung des Dokuments.
  • HTML/CSS-ExportgetHtml() und getCss().
Ein Plugin oder dein Setup-Code
  • BlockbibliothekDer Kern liefert keine aus – weder ein Preset, ein Plugin noch deins.
  • Rich Text EditingEin minimales RTE wird ausgeliefert; CKEditor/TinyMCE/Froala werden ausgetauscht.
  • Asset-PipelineDas Panel wird verschifft; der Lager dahinter nicht.
  • Speicheradapterlokaler und Remote-Speicher; dein API gehört dir.

Acht davon gehören direkt dir. Das ist die ehrliche Form des Werks, und es ist die gleiche Form, egal welchen visuellen Editor du wählst.

Wähle deinen Weg

Was baust du?

Der Kern ist bei allen gleich. Was sich unterscheidet, ist die Schicht darum herum – und jede davon hat ihren eigenen Leitfaden.

Vermeiden Sie diese

Häufige GrapesJS-Fehler

Jede einzelne davon kommt aus derselben Perspektive: den Editor als Produkt und nicht als eine einzige Schicht davon zu behandeln.

  1. Verwirrung von Blöcken mit Komponenten

    Du fügst einem Paletteneintrag Verhalten hinzu und fragst dich, warum das Objekt erst einmal auf der Leinwand passiert.

    Mach stattdessen das

    Ein Block erzeugt nur Dinge. Alles Verhalten – traits, Sperrungen, Rendering, Validierung – gehört zu dem von ihm erstellten Komponententyp.

  2. Alles im Browserzustand speichern

    Der Standardspeicher schreibt in localStorage. Es sieht so aus, als würde man speichern, bis ein Leser das Gerät wechselt, den Browser löscht oder dasselbe Projekt in zwei Tabs öffnet.

    Mach stattdessen das

    Entscheide, wo die Projekte wirklich stehen, bevor jemand Inhalte produziert, und setze storageManager: falsch, bis du es getan hast.

  3. Speicher wird überhaupt nicht konfiguriert

    Die Arbeit bleibt stillschweigend in einem nie entworfenen Store bestehen, und die Load Order wird unvorhersehbar, sobald mehrere Projekte existieren.

    Mach stattdessen das

    Konfigurieren Sie den Remote-Speicher, registrieren Sie einen benutzerdefinierten oder speichern Sie das Laufwerk und laden Sie sich selbst mit getProjectData() und loadProjectData().

  4. Erstellen eines Komponententyps für alles

    Vierzig nahezu identische Typen, jeder mit seinem eigenen traits und einer Farbpalette, die niemand navigieren kann.

    Mach stattdessen das

    Bevorzuge einen Typ mit traits gegenüber fünf Typen, die sich durch eine Farbe unterscheiden. Verlängere eingebaute Typen, anstatt sie neu zu bauen.

  5. Style Manager wird völlig offen gelassen

    Autoren greifen nach Float, absoluter Positionierung und 13px-Rändern, und jede Seite entfernt sich weiter vom Designsystem.

    Mach stattdessen das

    Listen Sie Ihre Sektoren explizit auf und verwenden Sie stylable / unstylable pro Komponente. Weniger Steuerungen erzeugen bessere Seiten.

  6. Behandlung von GrapesJS als vollständiges CMS

    Wochen verloren bei der Suche nach Nutzern, Rollen, Workflow- und Veröffentlichungsfunktionen, die nie da waren.

    Mach stattdessen das

    Lies zuerst die Verantwortungsaufteilung in Schritt 12. GrapesJS ist die Bearbeitungsebene; die CMS darum herum ist dein Produkt.

  7. Keine Planung der Asset-Speicherung

    Da kein Upload konfiguriert ist, werden die Bilder als base64 eingebettet und das gespeicherte Projekt wächst, bis es langsam lädt und umständlich zu bewegen ist.

    Mach stattdessen das

    Verdrahte den Asset Manager am ersten Tag an den echten Speicher, auch wenn dieser Speicher ein Ordner auf der Festplatte ist.

  8. Keinen Veröffentlichungs-Workflow definieren

    Du hast einen Editor, der speichert, und keine Antwort auf die Frage: "Wie wird das zu einer Seite, die ein Besucher öffnen kann?"

    Mach stattdessen das

    Skizziere die Pipeline von Schritt 8 an, bevor du den Editor baust. Das ändert in der Regel das, was du speicherst.

  9. Alle Anpassungen in einem Plugin zusammenführen

    Eine einzelne Datei mit 2.000 Zeilen, die Blöcke, Typen, Panels und Befehle registriert und nicht wiederverwendet oder in Teilen getestet werden kann.

    Mach stattdessen das

    Ein Plugin pro Organisation. Sie komponieren, und jedem kann Optionen angeboten werden.

  10. Responsives Verhalten bis zum Ende ignorieren

    Seiten, die direkt auf der Desktop-Leinwand aussehen und auf einem Handy brechen, mit Hunderten reiner Desktop-Regeln, die bereits geschrieben sind.

    Mach stattdessen das

    Wechsle die Geräte während des Baus. Styles werden pro Gerät geschrieben, also baut das Authoring mit einer Breite diese Breite ein.

Fehlerbehebung

Häufige Probleme

Die fünf Dinge, die bei einem ersten Build am ehesten schiefgehen könnten, und was man bei jedem überprüfen sollte.

Der Editor erscheint nicht

Meistens ein Befestigungsproblem und kein GrapesJS-Problem.

Prüfe

  • Das Container-Element existiert im DOM, sobald init() läuft.
  • Der Container hat eine Höhe – ein Null-Höhe-Element rendert einen Null-Höhen-Editor.
  • Das GrapesJS-Stylesheet ist geladen; ohne es ist der Editor zwar vorhanden, aber unsichtbar.
  • Die Initialisierung läuft auf dem Client, nicht während des Serverrenderings.

Styles fehlen oder der Editor sieht kaputt aus

Es sind zwei verschiedene Stylesheets beteiligt, und es ist einfach, keines von beiden zu laden.

Prüfe

  • grapesjs/dist/css/grapes.min.css wird für das eigene Chrome des Editors geladen.
  • Das CSS deiner Seite wird an die Leinwand übermittelt – es handelt sich um ein iframe, daher erreicht das Stylesheet deiner App es nicht automatisch.
  • Der Style Manager hat konfigurierte Sektoren; ein leeres Sektoren-Array rendert ein leeres Panel.
  • Die ausgewählte Komponente ist für die von Ihnen gesuchte Immobilie nicht mit unstylable gekennzeichnet.

Das Projekt speichert nicht

Hören Sie auf storage:error – GrapesJS meldet Ausfälle, anstatt sie zu schlucken.

Prüfe

  • storageManager ist konfiguriert, und der Typ entspricht einem tatsächlich registrierten Speicher.
  • urlStore ist erreichbar und gibt einen Erfolgsstatus zurück.
  • Zugangsdaten und Header werden gesendet – Remote-Speicher gibt standardmäßig die Anmeldedaten ein.
  • Es gibt keinen CORS-Fehler im Netzwerkpanel; ein blockierter Preflight sieht genau wie ein lautloser Fehler aus.

In React dupliziert oder stirbt der Editor beim erneuten Rendern

Fast immer ein Lebenszyklusproblem, kein GrapesJS-Problem.

Prüfe

  • init() läuft einmal, in einem Effekt mit leerem Abhängigkeitsarray.
  • destroy() läuft in der Reinigung – React 18 Strict Mode montiert Effekte zweimal während der Entwicklung.
  • React rendert Kinder nach init() nie in das Container-Element.

Der Build oder der Server stürzt beim Import ab

GrapesJS berührt das Fenster, wenn das Modul ausgewertet wird, daher kann es während des Serverrenderings nicht importiert werden.

Prüfe

  • Die Editor-Komponente wird nur clientseitig geladen – dynamischer Import mit deaktiviertem SSR oder ein Import innerhalb eines Effekts.
  • Das Stylesheet wird nicht in ein servergerendertes Modul importiert.
Nächste Schritte

Lerne GrapesJS weiter

Wohin man gehen soll, sobald der oben beschriebene Editor Sinn macht, ungefähr nach Schwierigkeitsgrad.

Tutorial oder Referenz?

Diese Seite ist das Build: installieren, konfigurieren, erweitern, ausliefern. Der vollständige Leitfaden ist die Referenz – die Architektur, das Ökosystem und die Begründung hinter dem Design. Die meisten Leute lesen am Ende beides, in dieser Reihenfolge.

Lies den vollständigen Leitfaden
Dienstleistungen

Brauchst du Hilfe beim Aufbau eines GrapesJS-Editors?

Der Großteil dieses Tutorials ist eine Tagesarbeit. Die darunterliegende Ebene – Speicher, Mandanten, Veröffentlichung, ein Editor, der zu deinem Designsystem passt – ist der Ort, an dem Projekte lang werden. GJS.Market kann diesen Teil übernehmen.

  • Individuelle Komponenten
  • Benutzerdefinierte Plugins
  • SaaS-Seitenbauer
  • Migrationen
  • Integrationen
  • White-Label-Editoren
  • Speicher- und API-Integration
  • Integration von React / Next.js / Vue / Angular
  • Produktionsarchitektur
FAQ

Häufig gestellte Fragen

Was ist GrapesJS?

GrapesJS ist ein Open-Source-Web-Builder-Framework: ein Drag-and-Drop-Visual-Editor, den Sie in Ihre eigene Anwendung einbetten. Er bietet Ihnen eine Leinwand, einen Komponentenbaum, einen Style-Manager, einen Asset-Manager und einen Export-Schritt und überlässt Konten, Speicher und Veröffentlichung der umliegenden Anwendung.

Ist GrapesJS kostenlos?

Ja. GrapesJS kann kostenlos heruntergeladen und genutzt werden, auch kommerziell. Es gibt keine Lizenzgebühr, keine Anzahl von Sitzplätzen und keinen gehosteten Dienst, den man kaufen muss – man betreibt ihn selbst. Optionale Plugins aus einem Marktplatz können bezahlt werden; der Editor selbst nicht.

Ist GrapesJS Open Source?

Ja. Der Core wird unter der BSD-3-Clause-Lizenz veröffentlicht, und der offizielle React-Wrapper @grapesjs/react unter MIT. Beide erlauben kommerzielle Nutzung und Modifikation. Der Quellcode ist auf GitHub und das Paket auf npm.

Wie installiere ich GrapesJS?

Entweder installiert npm grapesjs in einem Projekt mit einem Build-Schritt oder zwei Tags von einem CDN in einer einfachen HTML-Datei. Beides ergibt die gleiche Bibliothek; die CDN-Route benötigt überhaupt keine Werkzeuge. Denk daran, das Stylesheet ebenso wie das Skript zu laden – ohne es rendert der Editor, sieht aber kaputt aus.

Wie erstelle ich meinen ersten GrapesJS-Editor?

Füge deiner Seite ein leeres Element hinzu und rufe dann grapesjs.init({ container: '#gjs' }) auf. Das ist wirklich alles, was es braucht. In der Praxis willst du auch Größe, fromElement: falsch, damit der Editor das bestehende Markup nicht übernimmt, und storageManager: falsch, bis du entschieden hast, wo die Projekte liegen sollen.

Was ist ein GrapesJS-Block?

Ein Block ist ein Eintrag in der Palette, aus der ein Nutzer zieht. Er enthält ein Label, eine Kategorie, ein Symbol und den zu erstellenden Inhalt. Er hat kein eigenes Verhalten – er erzeugt nur Komponenten. Der GrapesJS-Kern liefert überhaupt keine Blöcke: Sie schreiben sie oder fügen ein voreingestelltes Plugin hinzu.

Was ist eine GrapesJS-Komponente?

Eine Komponente ist ein Knoten in der Leinwand: ein Modell mit einem Typ, Attributen, Stilen, Kindern und traits. Die Leinwand ist ein Baum von Komponenten, und das exportierte HTML wird aus diesem Baum generiert und nicht umgekehrt.

Wie erstelle ich eine benutzerdefinierte Komponente?

Rufen Sie editor.Components.addType('my-type', { model, view }) auf, wobei optional ein eingebauter Typ erweitert wird. Das Modell enthält Standardwerte, Kinder, traits und die Sperren — droppable, stylable, removable — die entscheiden, was ein Autor ändern darf. Fügen Sie isComponent hinzu, damit GrapesJS den Typ beim Parsen gespeicherter HTML erkennt.

Wie füge ich benutzerdefinierte Blöcke hinzu?

editor.Blocks.add('my-block', { label, category, media, content }). Inhalt benötigt entweder einen HTML-String oder eine Komponentendefinition wie { type: 'my-type' }. Die Objektform ist das, was du verwendest, sobald du deine eigenen Komponententypen hast.

Wie speichere ich GrapesJS-Projekte?

Konfigurieren Sie Storage Manager mit dem Typ: 'remote' und laden und speichern Sie URLs, registrieren Sie einen benutzerdefinierten Speicher bei editor.Storage.add() oder überspringen Sie ihn ganz und rufen Sie getProjectData() und loadProjectData() aus Ihrem eigenen Code auf. Der Speicher ist standardmäßig aktiviert und schreibt in localStorage, was selten das ist, was Sie in der Produktion wollen.

Wie exportiere ich HTML und CSS?

editor.getHtml() und editor.getCss(). Zwei Dinge, die du wissen solltest: getHtml() gibt die Leinwand zurück, die in einem Körperelement eingewickelt ist, und getCss() enthält den eigenen geschützten Leinwand-Reset von GrapesJS, es sei denn, du gibst avoidProtected: true.

Kann ich GrapesJS mit React verwenden?

Ja. Initialisiere es in einem Effekt mit einem leeren Abhängigkeitsarray, zerstöre es bei der Bereinigung und lass React nie wieder in den Container rendern. Es gibt auch einen offiziellen Wrapper, @grapesjs/react, falls du lieber die UI des Editors als React-Komponenten komponieren möchtest.

Kann ich GrapesJS mit Next.js verwenden?

Ja, mit einem Vorbehalt: GrapesJS berührt das Fenster im Modulumfang, muss also nur auf dem Client geladen werden – ein dynamischer Import mit deaktiviertem Serverrendering oder ein Import innerhalb eines Effekts. Alles andere ist wie bei normalem React.

Kann ich GrapesJS mit Vue oder Angular verwenden?

Ja. GrapesJS rendert in ein einfaches DOM-Element, also funktioniert es mit jedem Framework: Rufe init() im Mount Hook und destroy() im Teardown-Hook auf. Es gibt keinen offiziellen Vue- oder Angular-Wrapper – die Integration ist in beide Richtungen ein paar Zeilen.

Kann ich mit GrapesJS einen SaaS-Seitengenerator erstellen?

Ja, und das ist einer der häufigsten Gründe, es zu wählen. GrapesJS stellt die Bearbeitungsebene bereit; Ihre Anwendung stellt Konten, Berechtigungen, Mandanten, Speicher, Vorlagen und Veröffentlichung bereit. Zu wissen, dass diese Aufteilung vor Beginn ist, ist der Unterschied zwischen einem kurzen und einem langen.

Kann ich GrapesJS mit Plugins erweitern?

Ja. Ein Plugin ist eine Funktion, die die Editor-Instanz empfängt, sodass es Blöcke, Komponententypen, Befehle, Panels, traits und Style-Sektoren registrieren kann. Plugins mit usePlugin() registrieren; das ältere grapesjs.plugins.add() API ist veraltet.

Wo finde ich GrapesJS-Plugins?

Offiziell gepflegte Plugins befinden sich auf npm unter der GrapesJS-Organisation. GJS.Market katalogisiert Community- und kommerzielle Plugins nach Kategorie – Blöcke, Komponenten, Speicher, Assets, Rich-Text-Editoren, Presets und Entwicklertools – und jeder Eintrag auf dieser Seite stammt daraus.
Du bist dran

Bereit, mit GrapesJS zu bauen?

Beginne mit dem Kerneditor, passe ihn für dein Produkt an und erweitere ihn mit Plugins und Integrationen, wenn du mehr Funktionalität brauchst.

Fang hier an

Tutorial starten

Installiere GrapesJS und lasse in den nächsten zehn Minuten einen Editor laufen.

Geh zu Schritt 1
Erweitern

Plugins entdecken

Blöcke, Komponenten, Speicher und Asset-Anbieter aus dem GJS.Market-Katalog.

Plugins durchsuchen
Baue mit uns

Mit unserem Team bauen

Individuelle Komponenten, Speicherintegration und Produktionsarchitektur, erledigt mit dir.

Sprich mit uns

Alle Proben auf dieser Seite wurden mit GrapesJS 0.23.6 auf 2026-09-03 abgeglichen.