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:
- Use a
TEXT,MEDIUMTEXT, orJSONBcolumn type that supports large payloads. - 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
| Check | How to verify |
|---|---|
onReady has fired | Log inside the callback |
| You're saving JSON, not HTML | typeof data.body !== 'undefined' (JSON has body, HTML is a string) |
| DB column is large enough | Check schema; aim for MEDIUMTEXT / JSONB |
| JSON is not double-encoded | typeof stored === 'string' && stored.startsWith('"') means double-encoded |