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:

  • insertSection
  • duplicateSection
  • removeSection
  • moveSection
  • replaceSection
  • replaceAll
  • setProp and unsetProp
  • array item insert, duplicate, remove, and move
  • undo and redo

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.