Event Callbacks
Full signature reference for all Editor and useScrivrEditor event callbacks.
These callbacks are passed directly to new Editor(options). Framework adapters
(React, Vue, Svelte) wrap these in their own lifecycle hooks — see the relevant
package page for framework-specific options.
onChange
onChange?: (state: EditorState) => voidFired synchronously on every state change — any document edit or selection move that produces a new
EditorState. The state argument is the new (immutable) state.
This is the ideal hook for serializing the document for persistence:
const editor = new Editor({
extensions: [StarterKit],
onChange: (state) => {
const json = state.doc.toJSON();
localStorage.setItem('doc', JSON.stringify(json));
},
});When using <Scrivr /> and useScrivrEditor, you do not need onChange — use onUpdate instead.
The React adapter subscribes to the editor internally via editor.subscribe().
onFocusChange
onFocusChange?: (focused: boolean) => voidFired when the editor's hidden textarea gains or loses focus. focused is true on focus-in,
false on focus-out.
const editor = new Editor({
extensions: [StarterKit],
onFocusChange: (focused) => {
toolbar.classList.toggle('visible', focused);
},
});onCursorTick
onCursorTick?: (isVisible: boolean) => voidFired on every cursor blink tick (every ~530ms) and immediately after any user interaction that
moves the cursor. isVisible alternates between true and false to drive the blink animation.
This is the hook for custom overlay renderers that need to redraw the cursor:
const editor = new Editor({
extensions: [StarterKit],
onCursorTick: (isVisible) => {
overlayCanvas.drawCursor(isVisible);
},
});When using <Scrivr />, the ViewManager handles cursor repainting automatically.
You only need onCursorTick when building a completely custom rendering adapter.
Subscription vs Callbacks
For custom rendering adapters or framework-agnostic integrations, use editor.subscribe() instead
of callbacks:
const unsubscribe = editor.subscribe(() => {
// fires on every state change, focus change, and cursor tick
repaintOverlay();
});
// later
unsubscribe();editor.subscribe() is the underlying primitive that both useScrivrEditor and <Scrivr />
use internally.