Wie man GrapesJS in eine Remix-App integriert (vollständiger Leitfaden 2026)

GrapesJS in eine Remix-App einbetten: Mounte es clientseitig in useEffect, speichere Inhalte in einer Remix-Aktion und exportiere sauberes HTML/CSS.

DevFuture Development
DevFuture Development
May 21, 2026a month ago
8 Min-Lesezeit48-Ansichten

Warum GrapesJS zu Remix passt

GrapesJS benötigt den DOM, also initialisierst du ihn in einer Remix-App darin useEffect (nur für den Client) während die Loader und Aktionen von Remix Daten verarbeiten auf dem Server. Diese Anleitung mountet den Editor, speichert durch eine Remix-Aktion und exportiert HTML/CSS.

1. Den Editor clientseitig montieren

Erstellen app/routes/editor.tsxSie . Importiere GrapesJS im Effekt, damit es Läuft während SSR nie.

import { useEffect, useRef } from 'react';
import 'grapesjs/dist/css/grapes.min.css';

export default function Editor() {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    let editor: any;
    (async () => {
      const grapesjs = (await import('grapesjs')).default;
      editor = grapesjs.init({
        container: ref.current!,
        height: '100vh',
        fromElement: false,
        storageManager: false,
        components: '<h1>Hello from GrapesJS</h1>',
      });

      // Persist via a Remix action.
      document.getElementById('save')!.onclick = async () => {
        await fetch('/editor', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            html: editor.getHtml(),
            css: editor.getCss(),
            project: editor.getProjectData(),
          }),
        });
      };
    })();
    return () => editor?.destroy();
  }, []);

  return (
    <>
      <button id="save">Save</button>
      <div ref={ref} />
    </>
  );
}

2. Den Rettungswurf in einer Remix-Aktion übernehmen

// same app/routes/editor.tsx
import type { ActionFunctionArgs } from '@remix-run/node';
import { json } from '@remix-run/node';
import { savePage } from '~/models/page.server';

export async function action({ request }: ActionFunctionArgs) {
  const data = await request.json();
  await savePage('home', data);   // your DB write
  return json({ status: 'ok' });
}

Die Aktion läuft auf dem Server, sodass dein Datenbankclient nicht im Browser bleibt Bündel.

3. Gespeicherte Inhalte wieder laden

export async function loader() {
  return json(await getPage('home'));
}
// in the effect, after init:
// const saved = await fetch('/editor?_data=...'); editor.loadProjectData(saved.project);

Häufige Fallstricke in Remix

Code on a screen in a dark editor
Initialisieren Sie den Editor nur in useEffect; Halte den DB im Spiel.

Die Aufteilung zwischen Server und Client bei Remix ist der Punkt, an dem die Dinge schiefgehen. Das Importieren von GrapesJS auf Modul-Top-Ebene führt es während SSR aus und lässt die Route abstürzen – importiere es stattdessen dynamisch im Inneren useEffect . Behalten Sie alle Persistenz auf der Route action (Server) und importieren Sie niemals Ihren Datenbankclient in die Komponente, sonst wird er ins Browser-Bundle gedrängt. Wenn du ein gespeichertes Projekt lädst, lies es in und loader ruf editor.loadProjectData() es nach init auf – versuche nicht, den Editor-Status während SSR zu rendern. Schließlich kehre vom Effekt zurück, editor.destroy() damit clientseitige Übergänge keine Editor-Instanzen stapeln.

Voraussetzungen

Du brauchst Node.js 18+ und eine Remix 2-App. Kein Remix-spezifisches GrapesJS-Paket ist verfügbar erforderlich – der Editor ist nur browserfähig und die Loader/Actions von Remix verwalten Daten auf Der Server. Vertrautheit mit Routen, useEffect, und Remix-Aktionen ist Genug.

Fügen Sie benutzerdefinierte Blöcke zum Editor hinzu

Register ziehbare Blöcke mit dem Blockmanager nach init (innerhalb des Effekts):

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

Ziehe fertige Blockbibliotheken und Presets aus GJS.Market für ein reichhaltigeres Set.

Tieftauchen im Lager: Aktion + Lader

Behalte die Persistenz auf dem Server. POSTE das Projekt auf die Routen. action Und lesen Sie es von der loader, damit Ihr Datenbank-Client niemals durchsickert. In das Browser-Bundle:

export async function action({ request }) {
  const data = await request.json();
  await savePage('home', data);          // server-only DB write
  return json({ status: 'ok' });
}
export async function loader() {
  return json(await getPage('home'));    // returns the saved project
}

Nach Init rufen editor.loadProjectData(saved.project) Sie an, um eine Seite erneut zu öffnen.

Aufführungstipps

Importiere GrapesJS dynamisch im Inneren useEffect , damit es außerhalb der Hauptbündel und den Server-Renderpfad sowie zurückgeben editor.destroy() Client-seitige Übergänge stapeln also keine Instanzen. Code-Split-lastige Plugins dahinter die Funktion, die sie nutzt.

Sicherheitsaspekte

Authentifizieren und autorisieren Sie die Handlung vor dem Schreiben – akzeptieren Sie niemals ein nicht authentifiziertes POST, das eine Seite überschreibt. Desinfizieren Sie gespeicherte Markup-Ausgaben beim Ausgang, falls Nicht-Administratoren können bearbeiten. Validiere die Nutzlastgröße, damit ein großes Projekt nicht erschöpft werden kann Erinnerung.

Fehlerbehebung häufiger Fehler

"Fenster/Dokument ist nicht definiert" bedeutet, dass GrapesJS während SSR lief — importieren und es nur innerhalb useEffectiniten. Ein ungestylter Canvas bedeutet, dass der Stylesheet-Import fehlt. Ein Blank Editor bedeutet, dass die Container-Ref bei Init nicht bereit war. Hydrationswarnungen bedeutet normalerweise, dass du versucht hast, den Editor-Status während SSR zu rendern.

Wann man GrapesJS mit Remix verwenden sollte

GrapesJS passt, wenn deine Remix-App eine echte visuelle Seite oder einen E-Mail-Builder einbettet Benutzerkontrolle, mit eigenem Speicher und HTML-Ausgabe. Für Inline-Rich Text gilt ein Ein leichterer Editor reicht aus; für ganzseitige Komposition mit Layout, Styling und Sauberer Export ist GrapesJS die stärkere, vom MIT lizenzierte und selbstgehostete Wahl.

Nächste Schritte

Siehe die zugehörigen GrapesJS + React und GrapesJS + Next.js Guides, durchstöbern Sie die GrapesJS-Marktplatz oder starte mit dem GJS.Market-Startseite.

FAQ

Funktioniert GrapesJS mit Remix-Server-Rendering?

Ja – initialisiere es nur in In useEffect , damit es im Browser läuft. Die Die Route ist servergerendert; Nur die Editor-Instanz ist nur clientsbasiert.

Wie speichere ich GrapesJS-Daten in Remix?

POSTE die Projektdaten in eine Remix-Aktion und speichere sie in deiner Datenbank. Aktionen Laufe auf dem Server.

Wie lade ich gespeicherte Inhalte zurück?

Das gespeicherte Projekt aus einem Loader holen und aufrufen editor.loadProjectData(saved) nach grapesjs.init.

Weitere Tags:
Veröffentlicht May 21, 2026
Jul 3, 2026 aktualisiert
🔌 GJS.Market

Suchen Sie nach GrapesJS-Plugins?

Über 100 kuratierte Plugins, Presets und Vorlagen – sorgfältig auf Qualität ausgewählt und von der Community gepflegt.

Teilen Sie diesen BeitragTwitterFacebookLinkedIn
Veröffentlicht über
DevFuture Development
DevFuture Development
Besuchen Sie Shop →

Mehr von DevFuture Development

Entdecken Sie weitere aufschlussreiche Beiträge und bleiben Sie mit den neuesten Inhalten auf dem Laufenden.

Alle Beiträge ansehen

Premium-Plugins von DevFuture Development

Handverlesente, bezahlte Ergänzungen dieses Schöpfers erstellt.

Besuchen Sie Shop →