Hooks let you respond to editor lifecycle and changes with fine-grained control.

Hook Categories

Lifecycle

Initialization and teardown

Content

Document changes

Selection

Cursor and selection

Features

Comments, track changes, etc.

Lifecycle Hooks

onBeforeCreate

Called before the editor view is created.
editor
Editor
required
Editor instance (partially initialized)
onBeforeCreate: ({ editor }) => {
  console.log('Preparing editor...');
  // Set up external services
}

onCreate

Called when editor is fully initialized and ready.
editor
Editor
required
Fully initialized editor instance
onCreate: ({ editor }) => {
  console.log('Editor ready');
  editor.focus();
}

onDestroy

Called when editor is being destroyed.
No parameters passed. Clean up resources here.
onDestroy: () => {
  console.log('Cleaning up...');
  clearInterval(autoSaveTimer);
}

onFirstRender

Called after the first render completes.
onFirstRender: () => {
  measurePerformance();
  hideLoadingSpinner();
}

Content Hooks

onUpdate

Called when document content changes.
editor
Editor
required
Editor instance
transaction
Transaction
required
ProseMirror transaction
onUpdate: ({ editor, transaction }) => {
  if (transaction.docChanged) {
    const content = editor.getJSON();
    saveToBackend(content);
  }
}

onTransaction

Fires for every transaction including selection changes. Use sparingly.
editor
Editor
required
Editor instance
transaction
Transaction
required
ProseMirror transaction
duration
number
required
Transaction processing time in milliseconds
onTransaction: ({ editor, transaction, duration }) => {
  if (duration > 50) {
    console.warn(`Slow transaction: ${duration}ms`);
  }
}

onContentError

Called when content processing fails.
error
Error
required
Error object with details
editor
Editor
required
Editor instance
documentId
string
required
Document identifier
file
File | Blob
Original file that failed
onContentError: ({ error, editor }) => {
  if (error.recoverable) {
    editor.commands.clearInvalidNodes();
  } else {
    showErrorDialog(error);
  }
}

Selection Hooks

onSelectionUpdate

Called when selection changes (cursor movement).
editor
Editor
required
Editor instance
transaction
Transaction
required
ProseMirror transaction
onSelectionUpdate: ({ editor }) => {
  const { from, to } = editor.state.selection;
  updateSelectionUI(from, to);
  
  // Update formatting buttons
  toolbar.bold = editor.isActive('bold');
}

onFocus

Called when editor gains focus.
editor
Editor
required
Editor instance
event
FocusEvent
required
Browser focus event
onFocus: ({ editor, event }) => {
  showFormattingToolbar();
  trackEngagement('editor_focused');
}

onBlur

Called when editor loses focus.
editor
Editor
required
Editor instance
event
FocusEvent
required
Browser blur event
onBlur: ({ editor, event }) => {
  hideInlineMenus();
  saveCurrentState();
}

Feature Hooks

Comments Hooks

onCommentsUpdate

editor
Editor
required
Editor instance with updated comments
onCommentsUpdate: ({ editor }) => {
  const comments = editor.storage.comments.all();
  updateCommentsSidebar(comments);
}

onCommentsLoaded

editor
Editor
required
Editor instance
comments
Array<Comment>
required
Loaded comments array
replacedFile
boolean
Whether file was replaced
onCommentsLoaded: ({ editor, comments }) => {
  console.log(`Loaded ${comments.length} comments`);
  renderCommentsList(comments);
}

Track Changes Hooks

onTrackedChangesUpdate

editor
Editor
required
Editor instance with track changes
onTrackedChangesUpdate: ({ editor }) => {
  const changes = editor.storage.trackChanges.all();
  updateReviewPanel(changes);
}

Collaboration Hooks

onCollaborationReady

editor
Editor
required
Editor instance
ydoc
Y.Doc
required
Yjs document instance
onCollaborationReady: ({ editor, ydoc }) => {
  console.log('Collaboration active');
  showCollaboratorsCursors();
}

Common Patterns

Auto-save with Debouncing

import { debounce } from 'lodash';

const autoSave = debounce(async (content) => {
  await api.saveDocument(content);
}, 1000);

options: {
  onUpdate: ({ editor }) => {
    autoSave(editor.getJSON());
  }
}

Error Recovery

options: {
  onContentError: ({ error, editor }) => {
    console.error('Document error:', error);
  }
}

Performance Tips

Best practices for hooks:
  • Debounce expensive operations
  • Use onTransaction sparingly
  • Check transaction.docChanged before processing
  • Clean up resources in onDestroy
  • Batch initialization in onCreate