🚀 BlockNote AI is here! Access the early preview.
BlockNote Docs/Reference/Editor/Cursor & Selections

Cursor & Selections

BlockNote provides APIs to work with cursor positions and text selections, allowing you to understand where users are interacting with the editor and programmatically control the selection state.

Text Cursor

The text cursor represents the blinking vertical line where users type. BlockNote provides detailed information about the cursor's position and surrounding context.

TextCursorPosition Type

type TextCursorPosition = {
  block: Block;
  prevBlock: Block | undefined;
  nextBlock: Block | undefined;
};
  • block: The block currently containing the text cursor
  • prevBlock: The previous block at the same nesting level (undefined if first)
  • nextBlock: The next block at the same nesting level (undefined if last)

Getting Cursor Position

getTextCursorPosition(): TextCursorPosition;

// Usage
const cursorPos = editor.getTextCursorPosition();
console.log("Cursor is in block:", cursorPos.block.id);

Setting Cursor Position

setTextCursorPosition(
  targetBlock: BlockIdentifier,
  placement: "start" | "end" = "start"
): void;

// Usage
editor.setTextCursorPosition(blockId, "start");
editor.setTextCursorPosition(blockId, "end");

Parameters:

  • targetBlock: Block ID or Block object to position cursor in
  • placement: Whether to place cursor at start or end of block

Throws: Error if target block doesn't exist

Selections

Selections represent highlighted content spanning multiple blocks. BlockNote provides APIs to get and set selections programmatically.

Selection Type

type Selection = {
  blocks: Block[];
};
  • blocks: Array of all blocks spanned by the selection (including nested blocks)

Getting Current Selection

getSelection(): Selection | undefined;

// Usage
const selection = editor.getSelection();
if (selection) {
  console.log("Selected blocks:", selection.blocks.length);
}

Returns: Current selection or undefined if no selection is active

Setting Selection

setSelection(startBlock: BlockIdentifier, endBlock: BlockIdentifier): void;

// Usage
editor.setSelection(startBlockId, endBlockId);

Parameters:

  • startBlock: Block where selection should begin
  • endBlock: Block where selection should end

Requirements:

  • Both blocks must have content
  • Selection spans from start of first block to end of last block

Throws: Error if blocks don't exist or have no content

Common Use Cases

Highlighting Specific Content

// Select all content between two blocks
editor.setSelection(firstBlockId, lastBlockId);

// Get the selected content
const selection = editor.getSelection();
if (selection) {
  const selectedText = selection.blocks
    .map((block) => block.content)
    .join("\n");
}

Cursor Navigation

// Move cursor to specific block
editor.setTextCursorPosition(targetBlockId, "start");

// Get context around cursor
const cursorPos = editor.getTextCursorPosition();
if (cursorPos.prevBlock) {
  console.log("Previous block:", cursorPos.prevBlock.type);
}
if (cursorPos.nextBlock) {
  console.log("Next block:", cursorPos.nextBlock.type);
}

Selection-Based Operations

// Check if there's an active selection
const selection = editor.getSelection();
if (selection) {
  // Perform operations on selected blocks
  selection.blocks.forEach((block) => {
    console.log("Selected block:", block.id, block.type);
  });
} else {
  // No selection, work with cursor position
  const cursorPos = editor.getTextCursorPosition();
  console.log("Cursor in block:", cursorPos.block.id);
}

Best Practices

  1. Always check for undefined - Selections may not be active
  2. Use block references - Prefer Block objects over IDs when available
  3. Handle errors gracefully - Invalid block references will throw errors
  4. Consider user experience - Avoid disrupting user selections unnecessarily
  5. Group operations - Use transact() for multiple selection changes