Skip to main content

Multiple Editors

This page shows how to run two or more independent editor instances on the same page using createEditor() from the Vanilla JS SDK, including dynamic creation and destruction.

index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Multiple Editors</title>
<script src="https://cdn.pexelize.com/sdk/latest/pexelize.min.js"></script>
<style>
.toolbar { padding: 8px; display: flex; gap: 8px; border-bottom: 1px solid #ddd; }
.editor-wrapper { border: 1px solid #ccc; margin: 16px; }
.editor-container { height: 500px; }
</style>
</head>
<body>

<button id="add-editor">+ Add Editor</button>
<div id="editors"></div>

<script>
const EDITOR_KEY = 'your-editor-key';

// Track all live editor instances
const editors = new Map(); // id -> { instance, wrapper }
let counter = 0;

// --- Create an editor ---
function addEditor() {
counter++;
const id = `editor-${counter}`;

// Build DOM
const wrapper = document.createElement('div');
wrapper.className = 'editor-wrapper';
wrapper.innerHTML = `
<div class="toolbar">
<strong>${id}</strong>
<button data-action="save">Save JSON</button>
<button data-action="export">Export HTML</button>
<button data-action="destroy">Destroy</button>
</div>
<div id="${id}" class="editor-container"></div>
`;
document.getElementById('editors').appendChild(wrapper);

// Create the editor instance
const instance = pexelize.createEditor({
containerId: id,
editorKey: EDITOR_KEY,
onReady() {
console.log(`${id} ready`);
},
});

editors.set(id, { instance, wrapper });

// Toolbar actions
wrapper.querySelector('[data-action="save"]').addEventListener('click', () => {
instance.exportJson((json) => {
console.log(`${id} JSON:`, json);
localStorage.setItem(id, JSON.stringify(json));
alert(`${id} saved`);
});
});

wrapper.querySelector('[data-action="export"]').addEventListener('click', () => {
instance.exportHtml((data) => {
console.log(`${id} HTML length:`, data.html.length);
});
});

wrapper.querySelector('[data-action="destroy"]').addEventListener('click', () => {
removeEditor(id);
});
}

// --- Destroy an editor ---
function removeEditor(id) {
const entry = editors.get(id);
if (!entry) return;

entry.instance.destroy();
entry.wrapper.remove();
editors.delete(id);
console.log(`${id} destroyed. Active editors: ${editors.size}`);
}

// --- Bootstrap: start with 2 editors ---
document.getElementById('add-editor').addEventListener('click', addEditor);
addEditor();
addEditor();
</script>
</body>
</html>

Key points

  • Same editorKey works across instances -- multiple editors can share the same editorKey. Each instance runs in its own iframe with fully isolated state (design data, undo/redo, event listeners, configuration).
  • Unique container IDs -- every editor needs its own DOM element with a distinct id. Reusing the same ID will cause the second editor to fail silently. Framework wrappers generate unique container IDs automatically.
  • createEditor() returns an instance -- each instance has its own exportJson, exportHtml, loadDesign, and destroy methods that are scoped to that editor.
  • Always call destroy() -- when removing an editor from the page, call instance.destroy() first to clean up the iframe, event listeners, and internal state. Removing the DOM node alone will leak memory.
  • No instance limit -- there is no hard cap on editor count, but each instance loads its own iframe. More than 3-4 simultaneous editors may affect performance on lower-end machines.

React equivalent

In React, render multiple <PexelizeEditor> components with different refs:

function MultiEditor() {
const editorA = useRef(null);
const editorB = useRef(null);

return (
<>
<PexelizeEditor ref={editorA} editorKey={EDITOR_KEY} minHeight={500} />
<PexelizeEditor ref={editorB} editorKey={EDITOR_KEY} minHeight={500} />
</>
);
}

Each component manages its own iframe lifecycle automatically and calls destroy() on unmount.