Dollie Editor SDK guide
Editor State and History
Understand serialized page data, selection, undo, and external proposals.
usePageBuilderEditor owns the interactive state for one page editing session.
const editor = usePageBuilderEditor(
initialDefinition,
(nextDefinition) => {
setDraft(nextDefinition);
},
);
The change callback runs after definition-changing actions. Selecting a section does not dirty the page.
Common actions
The editor API includes:
insertSectionduplicateSectionremoveSectionmoveSectionreplaceSectionreplaceAllsetPropandunsetProp- array item insert, duplicate, remove, and move
undoandredo
Use these operations instead of mutating editor state directly.
Copy sections between pages
Select a section and press Cmd+C on macOS or Ctrl+C on Windows/Linux. On
the destination page, select a section and press Cmd+V / Ctrl+V, then choose
whether to insert the copied section above or below it. With no section
selected, paste inserts at the end after confirmation. The same actions are in
the section context menu on both the canvas and Layers panel.
The clipboard contains readable JSON in the public PageConfig wire format
with exactly one section. When a deprecated source section has canonicalId,
copy changes it to that shared section and materializes the legacy section's
default props before validation.
Relative inline image URLs resolve against the clipboard sourceUrl. Missing
destination illustrations inside declared slots become explicit
placeholder:medium values, including illustrations nested in arrays and
objects, so surrounding copy and array structure survive. An image reference
that is absent from the destination's local image inventory also becomes a
placeholder; an image-only slot receives a portable empty image value.
Unknown sections and malformed element references remain errors. Ordinary page validation stays strict: these compatibility transformations happen only while parsing a section clipboard payload, before the transformed section is validated against the destination catalog.
Programmatic integrations can use serializeSectionClipboard and
parseSectionClipboard for the same wire format and validation behavior.
Apply external proposals
Use replaceSection for a proposal that changes one section:
const selected = editor.state.sections[index];
if (selected) {
editor.replaceSection(selected.editorId, proposal);
}
Use replaceAll for a complete page proposal:
editor.replaceAll(proposedPage);
Both paths participate in the editor's history.
Save the wire format
const definition = serializeEditorState(editor.state);
Store that PageConfig, not the editor's temporary selection ids or undo stack.
Resetting from the server
initialDefinition initializes the hook; it is not a continuously controlled value. When switching to a different page or deliberately replacing the whole server document, remount the editor session with a stable page key or use a deliberate replacement flow.
Avoid silently replacing local work after an Inertia refresh or background fetch. Compare revisions and let the host decide how to handle conflicts.