Docs
Manipulating Blocks

Manipulating Blocks

Below, we explain the methods on editor you can use to read Blocks from the editor, and how to create / remove / update Blocks:

Common types

Before we dive into the methods, let's discuss some common types used in parameters:

Block Identifiers

The methods to access, insert, update, remove, or replace blocks, can require a BlockIdentifier as reference to an existing block in the document. This is either a string representing the block ID, or a Block object from which the ID is taken:

type BlockIdentifier = string | Block;

Partial Blocks

When retrieving blocks from the editor, you always receive complete Block objects. For updating or creating blocks, you don't need to pass all properties, and you can use a PartialBlock type instead:

type PartialBlock = {
  id?: string;
  type?: string;
  props?: Partial<Record<string, any>>; // exact type depends on "type"
  content?: string | InlineContent[] | TableContent;
  children?: PartialBlock[];
};

PartialBlock objects are almost the same as regular Block objects, but with all members optional and partial props. This makes updating or creating simpler blocks much easier. We'll see this below.

Accessing Blocks

There are a few different ways to retrieve Blocks from the editor:

Getting the Document

Retrieve a snapshot of the document (all top-level, non-nested blocks) in the editor using the following call:

document: Block[];
 
// Usage
const blocks = editor.document;

returns: The document; a snapshot of all top-level (non-nested) blocks in the editor.

We already used this for the Document JSON demo.

Getting a Specific Block

Use getBlock to retrieve a snapshot of a specific block in the editor:

getBlock(blockIdentifier: BlockIdentifier): Block | undefined;
 
// Usage
const block = editor.getBlock(blockIdentifier);

blockIdentifier: The identifier of an existing block that should be retrieved.

returns: The block that matches the identifier, or undefined if no matching block was found.

Traversing All Blocks

Use forEachBlock to traverse all blocks in the editor depth-first, and execute a callback for each block:

forEachBlock(
  callback: (block: Block) => boolean,
  reverse: boolean = false
): void;
 
// Usage
editor.forEachBlock((block) => {...});

callback: The callback to execute for each block. Returning false stops the traversal.

reverse: Whether the blocks should be traversed in reverse order.

Getting the hovered / selected Block

See Cursor & Selections to learn how to retrieve the block a user is interacting with.

Inserting New Blocks

Use insertBlocks to insert new blocks into the document:

insertBlocks(
  blocksToInsert: PartialBlock[],
  referenceBlock: BlockIdentifier,
  placement: "before" | "after" | "nested" = "before"
): void;
 
// Usage
editor.insertBlocks([{type: "paragraph", text: "Hello World"}], referenceBlock, placement)

blocksToInsert: An array of partial blocks that should be inserted.

referenceBlock: An identifier for an existing block, at which the new blocks should be inserted.

placement: Whether the blocks should be inserted just before, just after, or nested inside the referenceBlock. Inserts the blocks at the start of the existing block's children if "nested" is used.

If a block's id is undefined, BlockNote generates one automatically.

The method throws an error if the reference block could not be found.

Updating Blocks

Use updateBlock to update an existing block:

updateBlock(
  blockToUpdate: BlockIdentifier,
  update: PartialBlock
): void;
 
// Example to change a block type to paragraph
editor.updateBlock(blockToUpdate, { type: "paragraph" });

blockToUpdate: The identifier of an existing block that should be updated.

update: A partial blocks which defines how the existing block should be changed.

Since blockToUpdate is a PartialBlock object, some fields might not be defined. These undefined fields are kept as-is from the existing block.

Throws an error if the block to update could not be found.

Removing Blocks

Use removeBlocks to remove existing blocks from the document:

removeBlocks(
  blocksToRemove: BlockIdentifier[],
): void;
 
// Usage
editor.removeBlocks(blocksToRemove)

blocksToRemove: An array of identifier for existing blocks that should be removed.

Throws an error if any of the blocks could not be found.

Replacing Blocks

Use replaceBlocks to replace existing blocks in the editor with new blocks:

replaceBlocks(
  blocksToRemove: BlockIdentifier[],
  blocksToInsert: PartialBlock[],
): void;
 
// Usage
editor.replaceBlocks(blocksToRemove, blocksToInsert)

blocksToRemove: An array of identifier for existing blocks that should be replaced.

blocksToInsert: An array of partial blocks that the existing ones should be replaced with.

If the blocks that should be removed are not adjacent or are at different nesting levels, blocksToInsert will be inserted at the position of the first block in blocksToRemove.

Throws an error if any of the blocks to remove could not be found.

Nesting & Un-nesting Blocks

BlockNote also provides functions to nest & un-nest the block containing the Text Cursor.

Nesting Blocks

Use canNestBlock to check whether the block containing the Text Cursor can be nested (i.e. if there is a block above it at the same nesting level):

canNestBlock(): boolean;
 
// Usage
const canNestBlock = editor.canNestBlock();

Then, use nestBlock to actually nest (indent) the block:

nestBlock(): void;
 
// Usage
editor.nestBlock();

Un-nesting Blocks

Use canUnnestBlock to check whether the block containing the Text Cursor can be un-nested (i.e. if it's nested in another block):

canUnnestBlock(): boolean;
 
// Usage
const canUnnestBlock = editor.canUnnestBlock();

Then, use unnestBlock to un-nest the block:

unnestBlock(): void;
 
// Usage
editor.unnestBlock();