Custom Tools
Register your own drag-and-drop content tools with custom properties, icons, and HTML renderers.
- React
- Vue
- Angular
- Vanilla JS
import { useRef } from "react";
import { DragbleEditor, DragbleEditorRef } from "dragble-react-editor";
import type { DragbleToolConfig } from "dragble-types";
const testimonialTool: DragbleToolConfig = {
name: "testimonial",
label: "Testimonial",
icon: "https://cdn.example.com/icons/testimonial.svg",
position: 10,
properties: {
quote: {
label: "Quote",
type: "richtext",
value: "This product changed everything.",
},
authorName: { label: "Author Name", type: "text", value: "Jane Doe" },
authorTitle: {
label: "Author Title",
type: "text",
value: "CEO, Acme Inc.",
},
avatarUrl: { label: "Avatar", type: "image", value: "" },
starRating: {
label: "Stars",
type: "select",
value: "5",
options: ["1", "2", "3", "4", "5"],
},
},
renderer: (values) => `
<div style="padding:24px;background:#f9fafb;border-left:4px solid #6366f1;border-radius:8px;">
<p style="font-style:italic;font-size:16px;">"${values.quote}"</p>
<div style="display:flex;align-items:center;margin-top:12px;">
${values.avatarUrl ? `<img src="${values.avatarUrl}" width="40" height="40" style="border-radius:50%;margin-right:12px;" />` : ""}
<div>
<strong>${values.authorName}</strong>
<br/><span style="color:#6b7280;font-size:13px;">${values.authorTitle}</span>
</div>
</div>
<div style="margin-top:8px;">${"★".repeat(Number(values.starRating))}${"☆".repeat(5 - Number(values.starRating))}</div>
</div>
`,
};
function EditorWithTestimonial() {
const editorRef = useRef<DragbleEditorRef>(null);
const handleReady = () => {
editorRef.current?.editor?.registerTool(testimonialTool);
};
return (
<DragbleEditor
ref={editorRef}
editorKey="db_your_key"
editorMode="email"
onReady={handleReady}
/>
);
}
<template>
<DragbleEditor
ref="editorRef"
editor-key="db_your_key"
editor-mode="email"
@ready="onReady"
/>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { DragbleEditor } from "dragble-vue-editor";
import type { DragbleToolConfig } from "dragble-types";
const editorRef = ref<InstanceType<typeof DragbleEditor>>();
const testimonialTool: DragbleToolConfig = {
name: "testimonial",
label: "Testimonial",
icon: "https://cdn.example.com/icons/testimonial.svg",
position: 10,
properties: {
quote: {
label: "Quote",
type: "richtext",
value: "This product changed everything.",
},
authorName: { label: "Author Name", type: "text", value: "Jane Doe" },
authorTitle: {
label: "Author Title",
type: "text",
value: "CEO, Acme Inc.",
},
},
renderer: (values) => `
<div style="padding:24px;background:#f9fafb;border-left:4px solid #6366f1;">
<p style="font-style:italic;">"${values.quote}"</p>
<strong>${values.authorName}</strong><br/>
<span style="color:#6b7280;">${values.authorTitle}</span>
</div>
`,
};
function onReady() {
editorRef.value?.registerTool(testimonialTool);
}
</script>
import { Component, ViewChild } from "@angular/core";
import { DragbleEditorComponent } from "dragble-angular-editor";
import type { DragbleSDK, DragbleToolConfig } from "dragble-types";
@Component({
selector: "app-custom-tool",
standalone: true,
imports: [DragbleEditorComponent],
template: `
<dragble-editor
#editor
editorKey="db_your_key"
editorMode="email"
(ready)="onReady($event)"
></dragble-editor>
`,
})
export class CustomToolComponent {
@ViewChild("editor") editorComp!: DragbleEditorComponent;
private sdk: DragbleSDK | null = null;
onReady(sdk: DragbleSDK) {
this.sdk = sdk;
this.sdk.registerTool({
name: "testimonial",
label: "Testimonial",
icon: "https://cdn.example.com/icons/testimonial.svg",
position: 10,
properties: {
quote: {
label: "Quote",
type: "richtext",
value: "This product changed everything.",
},
authorName: { label: "Author Name", type: "text", value: "Jane Doe" },
},
renderer: (values) => `
<div style="padding:24px;background:#f9fafb;border-left:4px solid #6366f1;">
<p style="font-style:italic;">"${values.quote}"</p>
<strong>${values.authorName}</strong>
</div>
`,
});
}
}
dragble.init({
containerId: "editor-container",
editorKey: "db_your_key",
editorMode: "email",
callbacks: {
onReady: () => {
dragble.registerTool({
name: "testimonial",
label: "Testimonial",
icon: "https://cdn.example.com/icons/testimonial.svg",
position: 10,
properties: {
quote: {
label: "Quote",
type: "richtext",
value: "This product changed everything.",
},
authorName: { label: "Author Name", type: "text", value: "Jane Doe" },
authorTitle: {
label: "Author Title",
type: "text",
value: "CEO, Acme Inc.",
},
},
renderer: (values) => `
<div style="padding:24px;background:#f9fafb;border-left:4px solid #6366f1;">
<p style="font-style:italic;">"${values.quote}"</p>
<strong>${values.authorName}</strong><br/>
<span style="color:#6b7280;">${values.authorTitle}</span>
</div>
`,
});
},
},
});
:::tip Register tools after onReady
Custom tools must be registered after the editor has initialized. Always call registerTool() inside the onReady callback.
:::
Property types
Each property in the properties object configures one field in the tool's settings panel:
| Type | Description | Example value |
|---|---|---|
text | Single-line text input | 'Jane Doe' |
richtext | Rich text editor with formatting | '<b>Hello</b> world' |
image | Image picker (opens file manager) | 'https://...' |
color | Color picker | '#6366f1' |
select | Dropdown select | '5' (with options array) |
toggle | Boolean toggle switch | true |
number | Numeric input with optional min/max | 24 |
alignment | Horizontal alignment picker | 'center' |
Unregister a custom tool
Remove a previously registered tool by name:
dragble.unregisterTool("testimonial");
:::warning Design compatibility
Designs saved with a custom tool will show a placeholder if that tool is not registered when the design is loaded. Always register custom tools before calling loadDesign().
:::
DragbleToolConfig reference
interface DragbleToolConfig {
name: string; // Unique identifier
label: string; // Display name in the tool panel
icon: string; // URL to an SVG or PNG icon
position?: number; // Order in the tool panel
properties: Record<
string,
{
label: string;
type:
| "text"
| "richtext"
| "image"
| "color"
| "select"
| "toggle"
| "number"
| "alignment";
value: unknown; // Default value
options?: string[]; // For 'select' type only
editable?: boolean; // Lock the property (default: true)
}
>;
renderer: (values: Record<string, unknown>) => string; // Returns HTML
}
Method reference
| Method | Returns | Description |
|---|---|---|
registerTool(config) | void | Register a custom drag-and-drop tool |
unregisterTool(name) | void | Remove a registered custom tool |
Next steps
- Configure Tools — enable, disable, and reorder built-in tools
- Modules — save tool combinations as reusable content blocks
- Merge Tags — insert dynamic personalization tokens