Skip to main content

Design Not Saving

This page covers common reasons designs fail to persist or restore correctly.

Calling exportJson before the editor is ready

What you see: exportJson callback never fires, or it returns undefined.

Why it happens: The editor iframe hasn't finished initialising when you call the method.

Fix: Only call exportJson after the onReady callback has fired.

const editorRef = useRef(null);
const [ready, setReady] = useState(false);

const save = () => {
if (!ready) {
console.warn('Editor not ready yet');
return;
}
editorRef.current?.exportJson((json) => {
// safe to use
fetch('/api/designs', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ design: json }),
});
});
};

<PexelizeEditor ref={editorRef} onReady={() => setReady(true)} /* ... */ />

Saving HTML instead of JSON

What you see: You can export and email fine, but loadDesign() with the saved data does nothing or throws an error.

Why it happens: exportHtml returns rendered HTML meant for email clients. It cannot be loaded back into the editor. Only exportJson output is re-loadable.

Fix: Always persist the JSON from exportJson for restore, and use exportHtml only for the final send.

// Save (store this in your database)
editor.exportJson((json) => {
db.save('design_json', JSON.stringify(json));
});

// Load (pass the same JSON back)
const json = JSON.parse(db.get('design_json'));
editor.loadDesign(json);

// Export (only when sending the email)
editor.exportHtml((data) => {
emailService.send(data.html);
});

JSON too large for database column

What you see: The save API call returns a 413 or a database error like Data too long for column 'design'.

Why it happens: Complex designs with many blocks and embedded images can produce JSON payloads exceeding 1 MB. A VARCHAR(65535) or similar column silently truncates the data.

Fix:

  1. Use a TEXT, MEDIUMTEXT, or JSONB column type that supports large payloads.
  2. Optionally compress before storing.
-- MySQL
ALTER TABLE designs MODIFY COLUMN design_json MEDIUMTEXT;

-- PostgreSQL
ALTER TABLE designs ALTER COLUMN design_json TYPE jsonb;
// Optional: compress before saving
import pako from 'pako';

editor.exportJson((json) => {
const compressed = pako.deflate(JSON.stringify(json));
// store `compressed` as a BLOB
});

loadDesign with invalid or corrupt JSON

What you see: The editor shows a blank canvas after calling loadDesign, or logs Pexelize: invalid design format.

Why it happens: The JSON was truncated, double-encoded, or manually edited into an invalid state.

Fix: Validate the JSON before loading.

function safeLoadDesign(editor, raw) {
let json;
try {
json = typeof raw === 'string' ? JSON.parse(raw) : raw;
} catch (err) {
console.error('Invalid JSON:', err);
return false;
}

if (!json || !json.body) {
console.error('Missing required "body" key in design JSON');
return false;
}

editor.loadDesign(json);
return true;
}

A common mistake is double-encoding with JSON.stringify(JSON.stringify(json)). If loadDesign silently fails, try JSON.parse on the stored value first to see if it's a string-wrapped string.


Quick checklist

CheckHow to verify
onReady has firedLog inside the callback
You're saving JSON, not HTMLtypeof data.body !== 'undefined' (JSON has body, HTML is a string)
DB column is large enoughCheck schema; aim for MEDIUMTEXT / JSONB
JSON is not double-encodedtypeof stored === 'string' && stored.startsWith('"') means double-encoded