Design JSON Schema
The design JSON is the serializable document format used by Pexelize. This page documents the full structure you save to your database and load back into the editor.
Top-Level Structure
{
body: {
id: string;
rows: Row[];
headers?: Row[];
footers?: Row[];
values: BodyValues;
},
counters?: Record<string, number>;
schemaVersion: number;
_meta?: DesignMeta;
}
| Field | Type | Description |
|---|---|---|
body | object | The root container for all design content. |
body.id | string | Unique identifier for the body. |
body.rows | Row[] | Ordered list of content rows. |
body.headers | Row[] | Locked header rows (if configured). |
body.footers | Row[] | Locked footer rows (if configured). |
body.values | BodyValues | Body-level styling (background, width, fonts). |
counters | Record<string, number> | Internal counters for generating unique IDs. |
schemaVersion | number | Schema version for migration compatibility. |
_meta | DesignMeta | Editor metadata (last saved, editor version). |
body.values (BodyValues)
{
"backgroundColor": "#f5f5f5",
"contentWidth": "600px",
"contentAlignment": "center",
"fontFamily": "Arial, sans-serif",
"fontSize": "14px",
"textColor": "#333333",
"linkColor": "#0066cc",
"preheaderText": "Preview text shown in email clients",
"padding": "20px 0",
"borderRadius": "0px",
"_meta": {}
}
Row Structure
Each row is a horizontal section of the design containing one or more columns.
interface Row {
id: string;
cells: number[]; // column width ratios, e.g. [1] or [1, 1] or [2, 1]
columns: Column[];
values: RowValues;
_meta?: RowMeta;
}
RowValues
| Field | Type | Description |
|---|---|---|
backgroundColor | string | Row background color. |
backgroundImage | BackgroundImage | Row background image settings. |
padding | string | Row padding (e.g. '10px 20px'). |
borderTop | string | Top border CSS shorthand. |
borderBottom | string | Bottom border CSS shorthand. |
columnsBackgroundColor | string | Background color applied to all columns. |
fullWidth | boolean | Whether the row stretches to full viewport width. |
noStackMobile | boolean | Prevent columns from stacking on mobile. |
reverseStackMobile | boolean | Reverse column order when stacking on mobile. |
hideOnDesktop | boolean | Hide this row on desktop viewports. |
hideOnMobile | boolean | Hide this row on mobile viewports. |
displayCondition | DisplayCondition | null | Conditional rendering rule. |
locked | boolean | Whether the row is locked from editing. |
Example Row
{
"id": "row-1",
"cells": [1, 1],
"columns": [
{ "id": "col-1", "contents": [...], "values": {...} },
{ "id": "col-2", "contents": [...], "values": {...} }
],
"values": {
"backgroundColor": "#ffffff",
"padding": "20px 30px",
"fullWidth": false,
"noStackMobile": false
}
}
Column Structure
Each column lives inside a row and contains an ordered list of content blocks.
interface Column {
id: string;
contents: ContentBlock[];
values: ColumnValues;
}
ColumnValues
| Field | Type | Description |
|---|---|---|
backgroundColor | string | Column background color. |
padding | string | Column padding. |
borderTop | string | Top border CSS shorthand. |
borderRight | string | Right border CSS shorthand. |
borderBottom | string | Bottom border CSS shorthand. |
borderLeft | string | Left border CSS shorthand. |
Content Block Structure
Content blocks are the individual elements inside columns (text, image, button, etc.).
interface ContentBlock {
id: string;
type: ContentType;
values: Record<string, any>; // type-specific values
_meta?: ContentMeta;
}
type ContentType =
| 'text'
| 'image'
| 'button'
| 'divider'
| 'spacer'
| 'social'
| 'video'
| 'html'
| 'heading'
| 'menu'
| 'timer';
Common Content Values
These fields are shared across most content block types:
| Field | Type | Description |
|---|---|---|
containerPadding | string | Padding around the content block. |
anchor | string | Anchor ID for linking (e.g. #section-1). |
hideOnDesktop | boolean | Hide on desktop viewports. |
hideOnMobile | boolean | Hide on mobile viewports. |
Text Block Values
| Field | Type | Description |
|---|---|---|
text | string | HTML content of the text block. |
textAlign | 'left' | 'center' | 'right' | Text alignment. |
lineHeight | string | CSS line-height. |
linkColor | string | Color for links within the text. |
Image Block Values
| Field | Type | Description |
|---|---|---|
src | { url: string; width: number; height: number } | Image source. |
altText | string | Alt text for accessibility. |
action | { type: string; url?: string } | Click action (link, email, phone). |
textAlign | 'left' | 'center' | 'right' | Image alignment. |
fullWidth | boolean | Stretch image to full column width. |
Button Block Values
| Field | Type | Description |
|---|---|---|
text | string | Button label text. |
href | string | Button link URL. |
buttonColors | { color: string; backgroundColor: string; hoverColor?: string; hoverBackgroundColor?: string } | Button colors. |
size | { width: string; autoWidth: boolean } | Button sizing. |
textAlign | 'left' | 'center' | 'right' | Button alignment. |
borderRadius | string | Button corner radius. |
padding | string | Inner padding. |
_meta Fields
_meta objects store editor-internal metadata. They are preserved during save/load but should be treated as opaque.
interface DesignMeta {
editorVersion?: string; // editor version that created/modified the design
lastModified?: string; // ISO 8601 timestamp
templateId?: string; // source template ID, if any
}
interface RowMeta {
moduleId?: string; // if the row was inserted from a module
}
interface ContentMeta {
sourceType?: string; // how the block was created (drag, paste, ai)
}
Do not modify _meta fields manually. They are used internally by the editor for migration and tracking. Removing them won't break anything, but altering values may cause unexpected behavior.
The schemaVersion field is incremented when breaking changes are made to the JSON structure. The editor automatically migrates older designs when loaded.
Minimal Valid Design
{
"body": {
"id": "body-1",
"rows": [],
"values": {
"backgroundColor": "#ffffff",
"contentWidth": "600px",
"fontFamily": "Arial, sans-serif"
}
},
"schemaVersion": 1
}