Skip to content
FrameworkJavaScript

Caret API: move, focus, and set cursor position

Control cursor position and selection within the editor.

Reaching the editor instance

The methods below run on the editor you created with new Blok(). They are available once editor.isReady resolves.

TypeScript
// You already hold the instance returned by the constructor.
const editor = new Blok({ holder: 'editor' });
await editor.isReady;

// Call any API method on it.
editor.caret.setToLastBlock('end');

Methods

caret.setToFirstBlock(position?, offset?)

boolean

Set caret to the first block with optional position and offset.

When to use

position accepts 'start'/'end'/'default'; returns false if there's no block to land on.

TypeScript
// Set to start of first block
editor.caret.setToFirstBlock('start');

// Set to end of first block with offset
editor.caret.setToFirstBlock('end', 5);

caret.setToLastBlock(position?, offset?)

boolean

Set caret to the last block with optional position and offset.

When to use

Common after appending content — drop the caret at the end of the new last block with 'end'.

TypeScript
// Focus last block at end
editor.caret.setToLastBlock('end');

// Focus last block at start
editor.caret.setToLastBlock('start');

caret.setToPreviousBlock(position?, offset?)

boolean

Move caret to the previous block.

When to use

Moves relative to the focused block; returns false at the top edge, so use the return value to detect boundaries.

TypeScript
editor.caret.setToPreviousBlock('end');
// Caret now at end of previous block

caret.setToNextBlock(position?, offset?)

boolean

Move caret to the next block.

When to use

Mirror of setToPreviousBlock(); returns false at the bottom edge.

TypeScript
editor.caret.setToNextBlock('start');
// Caret now at start of next block

caret.setToBlock(blockOrIdOrIndex, position?, offset?)

boolean

Set caret to a specific block by BlockAPI, ID, or index.

When to use

The most flexible setter — target by BlockAPI, id, or index. Prefer id/BlockAPI over index, which shifts as blocks move.

Parameters

ParameterTypeRequiredDefaultDescription
blockOrIdOrIndexBlockAPI | string | numberRequiredTarget block, given as a BlockAPI instance, block id, or numeric index.
position'start' | 'end' | 'default''default'Where within the block to place the caret.
offsetnumber0Character offset from position within the target input.

Errors

  • blockOrIdOrIndex does not resolve to an existing block (unknown id or out-of-range index).

    (no error thrown — the call returns false)

    Check the boolean return value; setToBlock() never throws, so a falsy result is the only signal the target wasn't found.

TypeScript
// By index
editor.caret.setToBlock(0, 'end');
// → true if the caret moved, false if the target block doesn't exist

// By ID
editor.caret.setToBlock('block-123', 'start');

// By BlockAPI (getById can return null, so guard it)
const block = editor.blocks.getById('block-123');
if (block) {
  editor.caret.setToBlock(block);
}

caret.focus(atEnd?)

boolean

Set focus to the editor, optionally at the end of content.

When to use

Lightweight way to focus the editor without choosing a block; pass true for the end. Same as the top-level focus().

TypeScript
// Focus at start
editor.caret.focus();

// Focus at end
editor.caret.focus(true);

caret.updateLastCaretAfterPosition()

void

Update the "after" position of the most recent caret undo entry. Use after async caret movements.

When to use

Call after an async caret move so undo lands the caret where the user ended up, not where the op started.

TypeScript
// After moving caret asynchronously
requestAnimationFrame(() => {
  editor.caret.setToBlock(0);
  editor.caret.updateLastCaretAfterPosition();
});