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:
Precise targeting - Manipulate specific blocks even as document changes
Change tracking - Know exactly which blocks were modified
Collaborative editing - Reference blocks consistently across clients
Programmatic updates - Update document structure via APIs
sdBlockId is regenerated on every document load. If you need cross-session block references (e.g., headless CLI pipelines, multi-step AI workflows), use the Document API instead. editor.doc.find() returns addresses whose nodeId prefers DOCX-native paraId for imported blocks. This is best-effort stable, not a permanent global ID: Word or other tools can rewrite IDs during structural changes, and SuperDoc may rewrite duplicates on import.
Use case
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
Example:
const newParagraph = editor . schema . nodes . paragraph . create ({}, editor . schema . text ( 'New content' ))
editor . commands . replaceBlockNodeById ( 'block-123' , newParagraph )
import { SuperDoc } from 'superdoc' ;
import 'superdoc/style.css' ;
const superdoc = new SuperDoc ({
selector: '#editor' ,
document: yourFile ,
onReady : ( superdoc ) => {
const editor = superdoc . activeEditor ;
const newParagraph = editor . schema . nodes . paragraph . create ({}, editor . schema . text ( 'New content' ))
editor . commands . replaceBlockNodeById ( 'block-123' , newParagraph )
},
});
Parameters:
The sdBlockId of the node to replace
The replacement ProseMirror node
deleteBlockNodeById
Delete a block node by its ID
Completely removes the node from the document
Example:
editor . commands . deleteBlockNodeById ( 'block-123' )
import { SuperDoc } from 'superdoc' ;
import 'superdoc/style.css' ;
const superdoc = new SuperDoc ({
selector: '#editor' ,
document: yourFile ,
onReady : ( superdoc ) => {
const editor = superdoc . activeEditor ;
editor . commands . deleteBlockNodeById ( 'block-123' )
},
});
Parameters:
The sdBlockId of the node to delete
updateBlockNodeAttributes
Update attributes of a block node by its ID
Merges new attributes with existing ones
Example:
editor . commands . updateBlockNodeAttributes ( 'block-123' , { textAlign: 'center' })
import { SuperDoc } from 'superdoc' ;
import 'superdoc/style.css' ;
const superdoc = new SuperDoc ({
selector: '#editor' ,
document: yourFile ,
onReady : ( superdoc ) => {
const editor = superdoc . activeEditor ;
editor . commands . updateBlockNodeAttributes ( 'block-123' , { textAlign: 'center' })
},
});
Parameters:
The sdBlockId of the node to update
Helpers
getBlockNodes
Get all block nodes in the document
Example:
const blocks = editor . helpers . blockNode . getBlockNodes ()
console . log ( `Found ${ blocks . length } block nodes` )
import { SuperDoc } from 'superdoc' ;
import 'superdoc/style.css' ;
const superdoc = new SuperDoc ({
selector: '#editor' ,
document: yourFile ,
onReady : ( superdoc ) => {
const editor = superdoc . activeEditor ;
const blocks = editor . helpers . blockNode . getBlockNodes ()
console . log ( `Found ${ blocks . length } block nodes` )
},
});
Returns:
return
Array<BlockNodeInfo>
required
getBlockNodeById
Get a specific block node by its ID
Example:
const block = editor . helpers . blockNode . getBlockNodeById ( 'block-123' )
if ( block . length ) console . log ( 'Found:' , block [ 0 ]. node . type . name )
import { SuperDoc } from 'superdoc' ;
import 'superdoc/style.css' ;
const superdoc = new SuperDoc ({
selector: '#editor' ,
document: yourFile ,
onReady : ( superdoc ) => {
const editor = superdoc . activeEditor ;
const block = editor . helpers . blockNode . getBlockNodeById ( 'block-123' )
if ( block . length ) console . log ( 'Found:' , block [ 0 ]. node . type . name )
},
});
Parameters:
The sdBlockId to search for
Returns:
return
Array<BlockNodeInfo>
required
getBlockNodesByType
Get all block nodes of a specific type
Example:
const paragraphs = editor . helpers . blockNode . getBlockNodesByType ( 'paragraph' )
const headings = editor . helpers . blockNode . getBlockNodesByType ( 'heading' )
import { SuperDoc } from 'superdoc' ;
import 'superdoc/style.css' ;
const superdoc = new SuperDoc ({
selector: '#editor' ,
document: yourFile ,
onReady : ( superdoc ) => {
const editor = superdoc . activeEditor ;
const paragraphs = editor . helpers . blockNode . getBlockNodesByType ( 'paragraph' )
const headings = editor . helpers . blockNode . getBlockNodesByType ( 'heading' )
},
});
Parameters:
The node type name (e.g., ‘paragraph’, ‘heading’)
Returns:
return
Array<BlockNodeInfo>
required
getBlockNodesInRange
Get all block nodes within a position range
Example:
const selection = editor . state . selection
const blocksInSelection = editor . helpers . blockNode . getBlockNodesInRange (
selection . from ,
selection . to
)
import { SuperDoc } from 'superdoc' ;
import 'superdoc/style.css' ;
const superdoc = new SuperDoc ({
selector: '#editor' ,
document: yourFile ,
onReady : ( superdoc ) => {
const editor = superdoc . activeEditor ;
const selection = editor . state . selection
const blocksInSelection = editor . helpers . blockNode . getBlockNodesInRange (
selection . from ,
selection . to
)
},
});
Parameters:
Returns:
return
Array<BlockNodeInfo>
required
Types
BlockNodeInfo
Block node information object
Source code