Add data attributes to your rendered HTML to enable progressively richer visual editing:
Example of a fully annotated slide block:
If you can't modify the markup (e.g., using a 3rd party component library), use comment syntax to specify block attributes:
block-uid=xxxedit-text=title(.card-title)<!-- /hydra --> marks end of scope<!-- hydra block-uid=xxx /--> applies only to next sibling elementSupported attributes: block-uid, block-readonly, edit-text, edit-link, edit-media, block-add
Add data-linkable-allow to elements that should navigate during edit mode (paging links, facet controls, etc.):
The data-edit-text|edit-media|edit-link attributes support Unix-style paths to edit fields outside the current block:
This allows fixed parts of the page (like headers) to be editable without being inside a block.
Add data-block-readonly (or <!-- hydra block-readonly --> comment) to disable inline editing for all fields inside an element:
Or using comment syntax:
When rendering Slate nodes to DOM, your renderer must follow these rules for data-node-id:
p, strong, em, etc.) must have data-node-id matching the Slate node's nodeIddata-node-id as the inner elementhydra.js uses node-ids to map between Slate's data model and your DOM. When restoring cursor position after formatting changes, it walks your DOM counting Slate children.
A slate field's value is an array, but it always holds exactly one top-level node — a single paragraph, heading, list, or blockquote. Inline content (bold, links, …) lives in that node's children.
Editing can transiently produce more than one top-level node — pasting multiple paragraphs, pressing Enter, or a Backspace that demotes a list item to a paragraph ([ul, p]). Hydra normalizes that immediately:
value of a slate block, each extranode becomes its own slate block, inserted after the original in the same container (blocks_layout or object_list). This is how pressing Enter in a text block produces a new block.
non-slate block (e.g. a slateTable cell's value), or a container that's full or in table mode — the extra nodes' content merges back into the first node. No text is lost.
A frontend renderer can therefore always assume one top-level node per slate field; it never has to handle a multi-node value.
Slate data structure (value is an array but always contains a single root node):
Renderer:
Usage: