Skip to main content
Version: Latest

Modules

Save rows as reusable modules that appear in the Modules Library accordion for drag-and-drop insertion.

Module categories are canonicalized to lowercase by the SDK and editor. For example, "Banner", "banner", and "BANNER" are treated as the same banner category. The editor displays category labels with capitalized styling in the UI.

import { useRef } from "react";
import { DragbleEditor, DragbleEditorRef } from "dragble-react-editor";

function ModuleEditor() {
const editorRef = useRef<DragbleEditorRef>(null);

const handleReady = async () => {
const editor = editorRef.current?.editor;

editor?.setModules([
{
id: "hero-banner",
name: "Hero Banner",
category: "Banner", // normalized to "banner"
mode: "email",
type: "standard",
thumbnail: "https://cdn.example.com/thumbs/hero.png",
data: heroRowJson, // saved row JSON
},
{
id: "footer-standard",
name: "Standard Footer",
category: "footer",
mode: "email",
type: "standard",
thumbnail: "https://cdn.example.com/thumbs/footer.png",
data: footerRowJson,
},
]);
};

return (
<DragbleEditor
ref={editorRef}
editorKey="db_your_key"
editorMode="email"
onReady={handleReady}
onModuleSave={async (module) => {
await fetch("/api/modules", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(module),
});
}}
onModuleDelete={async (module) => {
const response = await fetch(`/api/modules/${module.id}`, {
method: "DELETE",
});

return response.ok
? { success: true }
: { success: false, error: "Failed to delete module" };
}}
/>
);
}

:::tip Module row JSON A module's data property contains the saved row JSON. When a user saves a row through the editor, onModuleSave returns the row data, rendered html, generated thumbnail, mode, type, and normalized lowercase category. :::

Modules Library configuration​

Configure the Modules Library accordion under options.appearance.sidePanel.modulesTab.modulesLibrary:

dragble.init({
containerId: "editor-container",
editorKey: "db_your_key",
options: {
appearance: {
sidePanel: {
modulesTab: {
modulesLibrary: {
visible: true,
defaultExpanded: true,
title: "Brand Modules",
categories: ["Banner", "POPULAR", "footer"],
defaultCategory: "Banner",
},
},
},
},
},
});

The SDK/editor stores those categories as banner, popular, and footer. The Modules Library dropdown displays them capitalized.

Synced modules​

Synced modules stay linked to the source. When you update a synced module, all designs using it reflect the changes on next load:

dragble.setModules([
{
id: "legal-footer",
name: "Legal Footer",
category: "footer",
mode: "email",
type: "synced", // Changes propagate to all designs using this module
data: legalFooterRowJson,
},
]);

:::warning Synced module edits Users cannot edit the content of a synced module inline. They must update the source module. Unsynced modules are fully editable after insertion. :::

Method reference​

MethodReturnsDescription
setModules(modules)voidReplace the available modules list. Categories normalize lowercase.
addModule(module)voidAppend a single module to the panel.
removeModule(id)voidRemove a module by ID.

Delete callback​

When the user deletes a module from the Modules Library, the editor calls onModuleDelete with the module metadata:

interface ModuleDeleteData {
id: string;
name?: string;
category?: string;
type?: "standard" | "synced";
mode?: "email" | "web";
}

Return { success: true } to confirm the delete. If you return { success: false, error }, the editor keeps the module in the library.

Next steps​