Manipulating Blocks
BlockNote operates on a block-based architecture, where all content is organized into discrete blocks. Understanding how to manipulate these blocks is fundamental to working with BlockNote effectively.
Block-Based Architecture
In BlockNote, everything is a block. A paragraph is a block, a heading is a block, a list item is a block, and even complex structures like tables are composed of blocks. This unified approach makes document manipulation consistent and predictable.
Core Block Operations
BlockNote provides a comprehensive set of operations for manipulating blocks, all working at the block level:
Reading Blocks
- Get the entire document - Retrieve all top-level blocks
- Get specific blocks - Access individual blocks by ID or reference
- Navigate relationships - Find previous, next, or parent blocks
- Traverse all blocks - Iterate through the entire document structure
// Get the entire document
const document: Block[] = editor.document;
// Get a specific block
const block = editor.getBlock(blockId);
// Get the previous block
const previousBlock = editor.getPreviousBlock(blockId);
// Get the next block
const nextBlock = editor.getNextBlock(blockId);
Creating Blocks
- Insert new blocks - Add blocks before or after existing ones
- Create complex structures - Build nested blocks like lists and tables
- Generate blocks programmatically - Create blocks from data or user input
// Insert a simple paragraph block
editor.insertBlocks(
[{ type: "paragraph", content: "Hello, world!" }],
referenceBlock,
);
// Create a complex block structure
editor.insertBlocks(
[
{ type: "heading", content: "My Heading" },
{ type: "paragraph", content: "Some content" },
{ type: "bulletListItem", content: "List item 1" },
{ type: "bulletListItem", content: "List item 2" },
],
referenceBlock,
);
Modifying Blocks
- Update existing blocks - Change block type, content, or properties
- Replace blocks - Swap one or more blocks with new blocks
- Move blocks - Reorder blocks by moving them up or down
- Nest and unnest - Change the hierarchy by indenting or outdenting blocks
// Change a block's type
editor.updateBlock(blockId, { type: "heading" });
// Update block content and properties
editor.updateBlock(blockId, {
content: "Updated content",
props: { level: 2 },
});
Removing Blocks
- Delete specific blocks - Remove individual blocks or groups of blocks
- Clear selections - Remove blocks based on user selection
// Remove specific blocks
editor.removeBlocks([blockId1, blockId2]);
// Replace blocks with new blocks
editor.replaceBlocks(
[oldBlockId],
[{ type: "paragraph", content: "New content" }],
);
Working with Cursor and Selections
- Read cursor position - Get information about where the user's cursor is located
- Set cursor position - Move the cursor to specific blocks
- Read selections - Access blocks currently selected by the user
- Set selections - Programmatically select ranges of blocks
// Get cursor position information
const cursorPosition = editor.getTextCursorPosition();
// Set cursor to a specific block
editor.setTextCursorPosition(blockId, "start");
// Get current selection
const selection = editor.getSelection();
// Set selection programmatically
editor.setSelection(startBlockId, endBlockId);
Best Practices
- Work with block references - Use existing blocks as references for positioning new blocks
- Handle errors gracefully - Operations can fail if blocks don't exist or are invalid
- Group related operations - Use transactions to group multiple block changes into a single undo/redo operation
- Consider user experience - Think about how your block manipulations affect the user's workflow
Next Steps
This overview covers the fundamental concepts of block manipulation in BlockNote. For detailed API reference and specific examples, see:
- Manipulating Blocks Reference - Complete API documentation
- Cursor & Selections - Working with user selections
- Block Types - Understanding different block types and their properties