Skip to main content
Events let you respond to editor lifecycle and content changes.

Lifecycle

onBeforeCreate

Called before the editor view is created.
onBeforeCreate: ({ editor }) => {
  // Set up external services
}
import { Editor } from 'superdoc/super-editor';

const editor = await Editor.open(yourFile, {
  element: document.querySelector('#editor'),
  onBeforeCreate: ({ editor }) => {
    // Set up external services
  },
});

onCreate

Called when editor is fully initialized and ready.
onCreate: ({ editor }) => {
  editor.focus();
}
import { Editor } from 'superdoc/super-editor';

const editor = await Editor.open(yourFile, {
  element: document.querySelector('#editor'),
  onCreate: ({ editor }) => {
    editor.focus();
  },
});

onDestroy

Called when editor is being destroyed. Clean up resources here.
onDestroy: () => {
  clearInterval(autoSaveTimer);
}
import { Editor } from 'superdoc/super-editor';

const editor = await Editor.open(yourFile, {
  element: document.querySelector('#editor'),
  onDestroy: () => {
    clearInterval(autoSaveTimer);
  },
});

onFirstRender

Called after the first render completes.
onFirstRender: () => {
  hideLoadingSpinner();
}
import { Editor } from 'superdoc/super-editor';

const editor = await Editor.open(yourFile, {
  element: document.querySelector('#editor'),
  onFirstRender: () => {
    hideLoadingSpinner();
  },
});

Content

onUpdate

Called when document content changes.
onUpdate: ({ editor, transaction }) => {
  if (transaction.docChanged) {
    saveToBackend(editor.getJSON());
  }
}
import { Editor } from 'superdoc/super-editor';

const editor = await Editor.open(yourFile, {
  element: document.querySelector('#editor'),
  onUpdate: ({ editor, transaction }) => {
    if (transaction.docChanged) {
      saveToBackend(editor.getJSON());
    }
  },
});

onContentError

Called when content processing fails.
onContentError: ({ error, editor, documentId }) => {
  console.error('Document error:', error);
}
import { Editor } from 'superdoc/super-editor';

const editor = await Editor.open(yourFile, {
  element: document.querySelector('#editor'),
  onContentError: ({ error, editor, documentId }) => {
    console.error('Document error:', error);
  },
});

Selection

onSelectionUpdate

Called when selection changes (cursor movement).
onSelectionUpdate: ({ editor }) => {
  toolbar.bold = editor.isActive('bold');
}
import { Editor } from 'superdoc/super-editor';

const editor = await Editor.open(yourFile, {
  element: document.querySelector('#editor'),
  onSelectionUpdate: ({ editor }) => {
    toolbar.bold = editor.isActive('bold');
  },
});

onFocus

Called when editor gains focus.
onFocus: ({ editor, event }) => {
  showFormattingToolbar();
}
import { Editor } from 'superdoc/super-editor';

const editor = await Editor.open(yourFile, {
  element: document.querySelector('#editor'),
  onFocus: ({ editor, event }) => {
    showFormattingToolbar();
  },
});

onBlur

Called when editor loses focus.
onBlur: ({ editor, event }) => {
  saveCurrentState();
}
import { Editor } from 'superdoc/super-editor';

const editor = await Editor.open(yourFile, {
  element: document.querySelector('#editor'),
  onBlur: ({ editor, event }) => {
    saveCurrentState();
  },
});

Subscribing after initialization

Use editor.on(...) and editor.off(...) to subscribe to events at any time after the editor is created. This is useful for adding listeners from external code that does not control the initial configuration.
editor.on('update', ({ editor }) => {
  const { counts } = editor.doc.info();
  updateDocumentStatsUI({
    words: counts.words,
    characters: counts.characters,
    trackedChanges: counts.trackedChanges,
    sdtFields: counts.sdtFields,
    lists: counts.lists,
  });
});
import { Editor } from 'superdoc/super-editor';

const editor = await Editor.open(yourFile, {
  element: document.querySelector('#editor'),
});

// Subscribe to updates after creation
const handler = ({ editor }) => {
  const { counts } = editor.doc.info();
  document.getElementById('stats').textContent =
    `${counts.words} words, ${counts.characters} characters, ` +
    `${counts.trackedChanges} tracked changes`;
};

editor.on('update', handler);

// Later, unsubscribe
editor.off('update', handler);
Constructor callbacks like onUpdate and runtime subscriptions like editor.on('update', ...) both fire on the same events. Use constructor callbacks when the listener is known at creation time, and editor.on(...) when adding listeners dynamically.

Features

onCommentsUpdate

onCommentsUpdate: ({ editor }) => {
  updateCommentsSidebar();
}
import { Editor } from 'superdoc/super-editor';

const editor = await Editor.open(yourFile, {
  element: document.querySelector('#editor'),
  onCommentsUpdate: ({ editor }) => {
    updateCommentsSidebar();
  },
});

onCommentsLoaded

onCommentsLoaded: ({ editor, comments }) => {
  console.log(`Loaded ${comments.length} comments`);
}
import { Editor } from 'superdoc/super-editor';

const editor = await Editor.open(yourFile, {
  element: document.querySelector('#editor'),
  onCommentsLoaded: ({ editor, comments }) => {
    console.log(`Loaded ${comments.length} comments`);
  },
});

onTrackedChangesUpdate

onTrackedChangesUpdate: ({ editor }) => {
  updateReviewPanel();
}
import { Editor } from 'superdoc/super-editor';

const editor = await Editor.open(yourFile, {
  element: document.querySelector('#editor'),
  onTrackedChangesUpdate: ({ editor }) => {
    updateReviewPanel();
  },
});

onCollaborationReady

onCollaborationReady: ({ editor, ydoc }) => {
  showCollaboratorsCursors();
}
import { Editor } from 'superdoc/super-editor';

const editor = await Editor.open(yourFile, {
  element: document.querySelector('#editor'),
  onCollaborationReady: ({ editor, ydoc }) => {
    showCollaboratorsCursors();
  },
});