Skip to main content

Custom Tools

Register your own drag-and-drop content tools with custom properties, icons, and HTML renderers.

import { useRef } from 'react';
import { PexelizeEditor, PexelizeEditorRef } from '@pexelize/react-editor';
import type { PexelizeToolConfig } from '@pexelize/editor-types';

const testimonialTool: PexelizeToolConfig = {
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<PexelizeEditorRef>(null);

const handleReady = () => {
editorRef.current?.editor?.registerTool(testimonialTool);
};

return (
<PexelizeEditor
ref={editorRef}
editorKey="pk_your_key"
editorMode="email"
onReady={handleReady}
/>
);
}
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:

TypeDescriptionExample value
textSingle-line text input'Jane Doe'
richtextRich text editor with formatting'<b>Hello</b> world'
imageImage picker (opens file manager)'https://...'
colorColor picker'#6366f1'
selectDropdown select'5' (with options array)
toggleBoolean toggle switchtrue
numberNumeric input with optional min/max24
alignmentHorizontal alignment picker'center'

Unregister a custom tool

Remove a previously registered tool by name:

pexelize.unregisterTool('testimonial');
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().

PexelizeToolConfig reference

interface PexelizeToolConfig {
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

MethodReturnsDescription
registerTool(config)voidRegister a custom drag-and-drop tool
unregisterTool(name)voidRemove 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