Automatically tracks block-level nodes with unique IDs for precise document manipulation. Essential for collaborative editing, change tracking, and programmatic document updates.

How It Works

Every block-level node (paragraphs, headings, etc.) automatically receives a unique sdBlockId attribute. This enables:
  1. Precise targeting - Manipulate specific blocks even as document changes
  2. Change tracking - Know exactly which blocks were modified
  3. Collaborative editing - Reference blocks consistently across clients
  4. Programmatic updates - Update document structure via APIs

Console Examples

After clicking in the editor above:
// Access the editor (available after interaction)
const editor = window.testEditor

// Get all blocks
const blocks = editor.helpers.blockNode.getBlockNodes()
console.log(`Found ${blocks.length} blocks`)

// Find a specific block
const block = blocks[0]
const id = block.node.attrs.sdBlockId
const found = editor.helpers.blockNode.getBlockNodeById(id)

// Update block attributes
editor.commands.updateBlockNodeAttributes(id, {
  textAlign: 'right',
  indent: { left: 40 }
})

// Get blocks by type
const headings = editor.helpers.blockNode.getBlockNodesByType('heading')
console.log(`${headings.length} headings found`)

Why you’d use this

  • Document APIs - Build REST APIs that manipulate specific blocks
  • Collaboration - Track who edited which blocks in real-time
  • Comments & Annotations - Attach metadata to specific blocks
  • Version Control - Diff documents at the block level
  • Templates - Replace placeholder blocks with dynamic content

Commands

replaceBlockNodeById

Replace a block node by its ID with new content
The replacement node should have the same type as the original
const newParagraph = editor.schema.nodes.paragraph.create({}, editor.schema.text('New content'))
replaceBlockNodeById('block-123', newParagraph)
Parameters:
id
string
required
The sdBlockId of the node to replace
contentNode
Object
required
The replacement ProseMirror node

deleteBlockNodeById

Delete a block node by its ID
Completely removes the node from the document
deleteBlockNodeById('block-123')
Parameters:
id
string
required
The sdBlockId of the node to delete

updateBlockNodeAttributes

Update attributes of a block node by its ID
Merges new attributes with existing ones
updateBlockNodeAttributes('block-123', { textAlign: 'center' })
updateBlockNodeAttributes('block-123', { indent: { left: 20 } })
Parameters:
id
string
required
The sdBlockId of the node to update
attrs
Object
required
Attributes to update

Helpers

getBlockNodes

Get all block nodes in the document
const blocks = editor.helpers.blockNode.getBlockNodes()
console.log(`Found ${blocks.length} block nodes`)
Returns: Array.<BlockNodeInfo> Array of block node info objects

getBlockNodeById

Get a specific block node by its ID
const block = editor.helpers.blockNode.getBlockNodeById('block-123')
if (block.length) console.log('Found:', block[0].node.type.name)
Parameters:
id
string
required
The sdBlockId to search for
Returns: Array.<BlockNodeInfo> Array containing the matching node (or empty)

getBlockNodesByType

Get all block nodes of a specific type
const paragraphs = editor.helpers.blockNode.getBlockNodesByType('paragraph')
const headings = editor.helpers.blockNode.getBlockNodesByType('heading')
Parameters:
type
string
required
The node type name (e.g., ‘paragraph’, ‘heading’)
Returns: Array.<BlockNodeInfo> Array of matching block nodes

getBlockNodesInRange

Get all block nodes within a position range
const selection = editor.state.selection
const blocksInSelection = editor.helpers.blockNode.getBlockNodesInRange(
  selection.from,
  selection.to
)
Parameters:
from
number
required
Start position
to
number
required
End position
Returns: Array.<BlockNodeInfo> Array of block nodes in the range

Types

BlockNodeInfo

Block node information object