> ## Documentation Index
> Fetch the complete documentation index at: https://superdoc-caio-pizzol-sd-docs-snippet-typecheck-2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Events

Events let you respond to editor lifecycle and content changes.

## Lifecycle

### `onBeforeCreate`

Called before the editor view is created.

<CodeGroup>
  ```javascript Usage theme={null}
  onBeforeCreate: ({ editor }) => {
    // Set up external services
  }
  ```

  ```javascript Full Example theme={null}
  import { Editor } from 'superdoc/super-editor';

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

### `onCreate`

Called when editor is fully initialized and ready.

<CodeGroup>
  ```javascript Usage theme={null}
  onCreate: ({ editor }) => {
    editor.focus();
  }
  ```

  ```javascript Full Example theme={null}
  import { Editor } from 'superdoc/super-editor';

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

### `onDestroy`

Called when editor is being destroyed. Clean up resources here.

<CodeGroup>
  ```javascript Usage theme={null}
  onDestroy: () => {
    clearInterval(autoSaveTimer);
  }
  ```

  ```javascript Full Example theme={null}
  import { Editor } from 'superdoc/super-editor';

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

### `onFirstRender`

Called after the first render completes.

<CodeGroup>
  ```javascript Usage theme={null}
  onFirstRender: () => {
    hideLoadingSpinner();
  }
  ```

  ```javascript Full Example theme={null}
  import { Editor } from 'superdoc/super-editor';

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

## Content

### `onUpdate`

Called when document content changes.

<CodeGroup>
  ```javascript Usage theme={null}
  onUpdate: ({ editor, transaction }) => {
    if (transaction.docChanged) {
      saveToBackend(editor.getJSON());
    }
  }
  ```

  ```javascript Full Example theme={null}
  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());
      }
    },
  });
  ```
</CodeGroup>

### `onContentError`

Called when content processing fails.

<CodeGroup>
  ```javascript Usage theme={null}
  onContentError: ({ error, editor, documentId }) => {
    console.error('Document error:', error);
  }
  ```

  ```javascript Full Example theme={null}
  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);
    },
  });
  ```
</CodeGroup>

## Selection

### `onSelectionUpdate`

Called when selection changes (cursor movement).

<CodeGroup>
  ```javascript Usage theme={null}
  onSelectionUpdate: ({ editor }) => {
    toolbar.bold = editor.isActive('bold');
  }
  ```

  ```javascript Full Example theme={null}
  import { Editor } from 'superdoc/super-editor';

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

### `onFocus`

Called when editor gains focus.

<CodeGroup>
  ```javascript Usage theme={null}
  onFocus: ({ editor, event }) => {
    showFormattingToolbar();
  }
  ```

  ```javascript Full Example theme={null}
  import { Editor } from 'superdoc/super-editor';

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

### `onBlur`

Called when editor loses focus.

<CodeGroup>
  ```javascript Usage theme={null}
  onBlur: ({ editor, event }) => {
    saveCurrentState();
  }
  ```

  ```javascript Full Example theme={null}
  import { Editor } from 'superdoc/super-editor';

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

## 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.

<CodeGroup>
  ```javascript Usage theme={null}
  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,
    });
  });
  ```

  ```javascript Full Example theme={null}
  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);
  ```
</CodeGroup>

<Info>
  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.
</Info>

## Features

### `onCommentsUpdate`

<CodeGroup>
  ```javascript Usage theme={null}
  onCommentsUpdate: ({ editor }) => {
    updateCommentsSidebar();
  }
  ```

  ```javascript Full Example theme={null}
  import { Editor } from 'superdoc/super-editor';

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

### `onCommentsLoaded`

<CodeGroup>
  ```javascript Usage theme={null}
  onCommentsLoaded: ({ editor, comments }) => {
    console.log(`Loaded ${comments.length} comments`);
  }
  ```

  ```javascript Full Example theme={null}
  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`);
    },
  });
  ```
</CodeGroup>

### `onTrackedChangesUpdate`

<CodeGroup>
  ```javascript Usage theme={null}
  onTrackedChangesUpdate: ({ editor }) => {
    updateReviewPanel();
  }
  ```

  ```javascript Full Example theme={null}
  import { Editor } from 'superdoc/super-editor';

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

### `onCollaborationReady`

<CodeGroup>
  ```javascript Usage theme={null}
  onCollaborationReady: ({ editor, ydoc }) => {
    showCollaboratorsCursors();
  }
  ```

  ```javascript Full Example theme={null}
  import { Editor } from 'superdoc/super-editor';

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