> ## Documentation Index
> Fetch the complete documentation index at: https://docs.superdoc.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

Configuration is passed when creating a SuperDoc instance. Only two fields are required.

## Quick start

```javascript theme={null}
new SuperDoc({
  selector: "#editor", // Required: Where to render
  document: "contract.docx", // Required: What to load
});
```

## Core parameters

<ParamField path="selector" type="string | HTMLElement" required>
  DOM selector or element where SuperDoc will mount.

  ```javascript theme={null}
  selector: '#editor'
  // or
  selector: document.querySelector('.my-editor')
  ```
</ParamField>

<ParamField path="document" type="Document | string | File" required>
  Document to load.

  Can be a `Document (Object)`, `string` or `File`

  <Expandable title="Supported formats">
    * `Document` Object

    ```json theme={null}
    {
      id: 'doc-123', // string
      type: 'pdf', // string, can be 'docx' or 'pdf'
      data: File, // local File or Blob source
      // OR
      url: 'https://example.com/report.pdf' // remote URL source
    }
    ```

    * `string` - URL to fetch
    * `File` - From file input
  </Expandable>

  <Note>
    For a `Document` object, use `data` for local files and `url` for remote files.
    Provide one source field (`data` or `url`) per document object.
    Use `documents` array for multiple documents instead.
  </Note>
</ParamField>

<ParamField path="documents" type="Document[]">
  Multiple documents to load (alternative to single `document`)

  ```javascript theme={null}
  documents: [
    { id: 'doc-1', type: 'docx', data: fileObject },
    { id: 'doc-2', type: 'pdf', url: 'report.pdf' }
  ]
  ```

  <Expandable title="Supported formats">
    * `File` - From file input (e.g., from `<input type="file">`)
    * `string` (URL) - To fetch the document
  </Expandable>
</ParamField>

<ParamField path="superdocId" type="string">
  Unique identifier for this SuperDoc instance
  <Note>Auto-generated UUID if not provided</Note>
</ParamField>

## User & permissions

<ParamField path="user" type="Object">
  Current user information

  <Expandable title="User properties">
    <ParamField path="name" type="string" required>
      Display name
    </ParamField>

    <ParamField path="email" type="string" required>
      Email address
    </ParamField>

    <ParamField path="image" type="string">
      Avatar URL
    </ParamField>
  </Expandable>
</ParamField>

<ParamField path="users" type="User[]" default="[]">
  All users with document access. Used for @mentions and collaboration.
</ParamField>

<ParamField path="role" type="string" default="'editor'">
  User permission level

  <Expandable title="Available roles">
    * `editor` - Full editing capabilities
    * `viewer` - Read-only access
    * `suggester` - Can only suggest changes
  </Expandable>

  <Warning>Role overrides documentMode when more restrictive</Warning>
</ParamField>

<ParamField path="documentMode" type="string" default="'editing'">
  Initial document mode

  <Expandable title="Document modes">
    * `editing` - Normal editing
    * `viewing` - Read-only display
    * `suggesting` - Track changes enabled
  </Expandable>

  <Info>See the [Track Changes module](/editor/built-in-ui/track-changes) for accept/reject commands, the Document API, and configuration. The [runnable example](https://github.com/superdoc-dev/superdoc/tree/main/examples/editor/built-in-ui/track-changes) shows a complete workflow.</Info>
</ParamField>

<ParamField path="comments" type="Object">
  Viewing-mode visibility controls for standard comments

  <Expandable title="properties" defaultOpen>
    <ParamField path="comments.visible" type="boolean" default="false">
      Show comment highlights and threads when `documentMode` is `viewing`
    </ParamField>
  </Expandable>
</ParamField>

<ParamField path="trackChanges" type="Object" deprecated>
  <Warning>**Deprecated**: Use [`modules.trackChanges`](#track-changes-module) instead. This top-level key remains supported as an alias and will emit a one-time console warning.</Warning>

  <Expandable title="properties" defaultOpen>
    <ParamField path="trackChanges.visible" type="boolean" default="false">
      Show tracked-change markup and threads when `documentMode` is `viewing`.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField path="permissionResolver" type="function">
  Override permission checks for comments and tracked changes. By default, editors can resolve, edit, and delete any user's comments and tracked changes. Use this to restrict actions.

  ```javascript theme={null}
  const superdoc = new SuperDoc({
    user: { name: 'Alex Editor', email: 'alex@example.com' },
    permissionResolver: ({ permission, trackedChange, defaultDecision }) => {
      if (permission === 'RESOLVE_OTHER' && trackedChange) {
        return false; // Block accepting suggestions from other authors
      }
      return defaultDecision;
    },
  });
  ```

  <Note>Return `false` to block an action. Return `true` or `undefined` to fall back to the built-in permission matrix. See [Comments > Permission resolver](/editor/built-in-ui/comments#permission-resolver) for the full list of permission types.</Note>
</ParamField>

## Modules

<ParamField path="modules" type="Object">
  Configure optional modules
</ParamField>

### Collaboration module

<ParamField path="modules.collaboration" type="Object">
  Real-time collaboration settings

  <Expandable title="properties" defaultOpen>
    <ParamField path="modules.collaboration.ydoc" type="Y.Doc" required>
      Shared Yjs document instance for this collaborative session.
    </ParamField>

    <ParamField path="modules.collaboration.provider" type="Object" required>
      Yjs-compatible provider instance (for example LiveblocksYjsProvider or WebsocketProvider from y-websocket).
    </ParamField>
  </Expandable>
</ParamField>

<Note>
  SuperDoc uses a provider-agnostic collaboration contract: `modules.collaboration = { ydoc, provider }`.
  Provider setup remains in your app code. See [Collaboration configuration](/editor/collaboration/configuration) and [Collaboration guides](/editor/collaboration/overview).
</Note>

### Comments module

<ParamField path="modules.comments" type="Object">
  Comments system configuration

  <Expandable title="properties" defaultOpen>
    <ParamField path="element" type="string | HTMLElement">
      DOM element for comments list
    </ParamField>

    <ParamField path="displayMode" type="'sidebar' | 'inline' | 'auto'" default="'sidebar'">
      Comments/track-changes bubble display policy.

      * `'sidebar'`: always use the right sidebar.
      * `'inline'`: always use compact inline popover mode.
      * `'auto'`: switch between sidebar and compact inline mode based on available container width.
    </ParamField>

    <ParamField path="compactBreakpointPx" type="number">
      Optional fixed compact-mode threshold override in pixels (used when `displayMode: 'auto'`).
      When set, compact mode is active when measured available width is below this value.
    </ParamField>

    <ParamField path="compactMeasurementSelector" type="string">
      Optional CSS selector for the element used to measure available width in `displayMode: 'auto'`.
      Use this when SuperDoc is embedded in custom flex/grid shells and the default fallback target is not representative.
    </ParamField>

    <ParamField path="allowResolve" type="boolean" default="true">
      Allow resolving comments
    </ParamField>

    <ParamField path="useInternalExternalComments" type="boolean">
      Dual comment system
    </ParamField>

    <ParamField path="permissionResolver" type="function">
      Comments-only override for the permission resolver
    </ParamField>
  </Expandable>
</ParamField>

### Track changes module

<ParamField path="modules.trackChanges" type="Object">
  Track changes configuration. Supersedes the top-level `trackChanges` and `layoutEngineOptions.trackedChanges` keys, which remain supported as deprecated aliases.

  <Expandable title="properties" defaultOpen>
    <ParamField path="modules.trackChanges.visible" type="boolean" default="false">
      Show tracked-change markup and threads when `documentMode` is `viewing`.
    </ParamField>

    <ParamField path="modules.trackChanges.mode" type="'review' | 'original' | 'final' | 'off'">
      Rendering mode for tracked changes.

      * `'review'`: show insertions and deletions inline (default for editing/suggesting).
      * `'original'`: show the document as it existed before tracked changes (default for viewing when `visible` is `false`).
      * `'final'`: show the document with changes applied.
      * `'off'`: disable tracked-change rendering.
    </ParamField>

    <ParamField path="modules.trackChanges.enabled" type="boolean" default="true">
      Whether the layout engine treats tracked changes as active.
    </ParamField>

    <ParamField path="modules.trackChanges.replacements" type="'paired' | 'independent'" default="'paired'">
      How a tracked replacement (adjacent insertion + deletion created by typing over selected text) surfaces in the UI and API.

      * `'paired'` (default, Google Docs model): the two halves share one id and resolve together with a single accept/reject click.
      * `'independent'` (Microsoft Word / ECMA-376 §17.13.5 model): each insertion and each deletion has its own id, is addressable on its own, and resolves independently.
    </ParamField>

    <ParamField path="modules.trackChanges.authorColors" type="Object">
      Resolve one tracked-change highlight color per author. Use this when imported DOCX files contain reviewers your app does not know ahead of time, or when you want a stable author legend in a custom review UI.

      <Expandable title="properties">
        <ParamField path="modules.trackChanges.authorColors.enabled" type="boolean" default="true">
          Set to `false` to use the default tracked-change colors.
        </ParamField>

        <ParamField path="modules.trackChanges.authorColors.overrides" type="Record<string, string>">
          Exact color overrides keyed by author email or author name. Email matches first, then name.
        </ParamField>

        <ParamField path="modules.trackChanges.authorColors.resolve" type="(author) => string | undefined">
          Callback for authors not covered by `overrides`. Receives `{ name, email, image }`. Return any CSS color string, or `undefined` to use SuperDoc's deterministic fallback color.
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

```javascript theme={null}
new SuperDoc({
  selector: '#editor',
  document: 'contract.docx',
  documentMode: 'viewing',
  modules: {
    trackChanges: { visible: true, mode: 'review' },
  },
});
```

Assign per-author tracked-change colors without injecting CSS selectors:

```javascript theme={null}
new SuperDoc({
  selector: '#editor',
  document: 'contract.docx',
  modules: {
    trackChanges: {
      visible: true,
      authorColors: {
        overrides: {
          'alice@example.com': '#1f6feb',
          'Bob Reviewer': '#d1242f',
        },
        resolve: (author) => {
          if (author.email?.endsWith('@outside-counsel.com')) return '#8250df';
          return undefined; // SuperDoc assigns a stable fallback color
        },
      },
    },
  },
});
```

Opt into Microsoft Word / ECMA-376-style independent revisions, where each insertion and each deletion has its own id and resolves on its own:

```javascript theme={null}
new SuperDoc({
  selector: '#editor',
  document: 'contract.docx',
  modules: {
    trackChanges: { replacements: 'independent' },
  },
});
```

### Toolbar module

<ParamField path="modules.toolbar" type="Object">
  Toolbar configuration

  <Expandable title="properties" defaultOpen>
    <ParamField path="selector" type="string">
      CSS selector for the toolbar container (e.g. `'#toolbar'`)
    </ParamField>

    <ParamField path="groups" type="string[]" default="['left', 'center', 'right']">
      Layout groups
    </ParamField>

    <ParamField path="icons" type="Object">
      Custom icon overrides
    </ParamField>

    <ParamField path="texts" type="Object">
      Text label overrides
    </ParamField>

    <ParamField path="fonts" type="string[]">
      Available font families. See [Toolbar fonts](/editor/built-in-ui/toolbar#font-configuration) for details.

      <Info>Custom fonts from DOCX files will display in the toolbar but won't be selectable unless loaded in your app and added here.</Info>
    </ParamField>

    <ParamField path="hideButtons" type="boolean" default="true">
      Hide when inactive
    </ParamField>

    <ParamField path="responsiveToContainer" type="boolean" default="false">
      Container-based responsive sizing
    </ParamField>
  </Expandable>
</ParamField>

### Surface defaults

<ParamField path="modules.surfaces" type="Object">
  Optional defaults and resolver for SuperDoc surfaces.

  <Expandable title="properties" defaultOpen>
    <ParamField path="modules.surfaces.resolver" type="function">
      Resolve intent-based surface requests opened with `kind`
    </ParamField>

    <ParamField path="modules.surfaces.dialog" type="Object">
      Default dialog options
    </ParamField>

    <ParamField path="modules.surfaces.dialog.closeOnEscape" type="boolean" default="true">
      Close dialogs on `Escape`
    </ParamField>

    <ParamField path="modules.surfaces.dialog.closeOnBackdrop" type="boolean" default="true">
      Close dialogs on backdrop click
    </ParamField>

    <ParamField path="modules.surfaces.dialog.maxWidth" type="string | number">
      Default dialog max-width
    </ParamField>

    <ParamField path="modules.surfaces.floating" type="Object">
      Default floating-surface options
    </ParamField>

    <ParamField path="modules.surfaces.floating.placement" type="'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center'" default="'top-right'">
      Default floating placement
    </ParamField>

    <ParamField path="modules.surfaces.floating.width" type="string | number">
      Default floating width
    </ParamField>

    <ParamField path="modules.surfaces.floating.maxWidth" type="string | number">
      Default floating max-width
    </ParamField>

    <ParamField path="modules.surfaces.floating.maxHeight" type="string | number">
      Default floating max-height
    </ParamField>

    <ParamField path="modules.surfaces.floating.closeOnEscape" type="boolean" default="true">
      Close floating surfaces on `Escape`
    </ParamField>

    <ParamField path="modules.surfaces.floating.closeOnOutsidePointerDown" type="boolean" default="false">
      Close floating surfaces when clicking outside
    </ParamField>

    <ParamField path="modules.surfaces.floating.autoFocus" type="boolean" default="true">
      Move focus into the first focusable child on open
    </ParamField>

    <ParamField path="modules.surfaces.findReplace" type="false | true | Object" default="false">
      Built-in find/replace popover for editor-backed documents. Disabled by default; set to `true` for the built-in UI, or pass an object to customize text, disable replace actions, provide a custom component or render function, or add a runtime resolver. See [Surfaces: Built-in Find and Replace](/editor/superdoc/surfaces#built-in-find-and-replace).
    </ParamField>

    <ParamField path="modules.surfaces.passwordPrompt" type="false | true | Object" default="true">
      Built-in password prompt for encrypted DOCX files. Enabled by default when omitted; set to `false` to disable, `true` for defaults, or pass an object to customize text, provide a custom component or render function, or add a per-document resolver. See [Surfaces: Built-in password prompt](/editor/superdoc/surfaces#built-in-password-prompt).
    </ParamField>
  </Expandable>
</ParamField>

<Note>
  You only need `modules.surfaces` if you want shared defaults, a central resolver, or to enable/configure built-in surface behaviors like find/replace and the password prompt. Direct `superdoc.openSurface(...)` calls do not require any special setup.
</Note>

See [Surfaces](/editor/superdoc/surfaces) for the full API and examples.

<ParamField path="modules.slashMenu" type="Object" deprecated>
  <Warning>**Deprecated**: Use `modules.contextMenu` instead. See the [Context Menu module](/editor/built-in-ui/context-menu) for configuration options.</Warning>
</ParamField>

### Content controls module

<ParamField path="modules.contentControls" type="Object">
  Content-control rendering configuration.

  <Expandable title="properties" defaultOpen>
    <ParamField path="modules.contentControls.chrome" type="'default' | 'none'" default="'default'">
      Built-in content-control chrome mode.

      * `'default'`: Word-like built-in chrome (labels, borders, hover, selected outline)
      * `'none'`: disables built-in chrome while keeping SDT data/geometry and `data-sdt-*` wrappers
    </ParamField>
  </Expandable>
</ParamField>

Use this when you want to keep content controls in the document but disable SuperDoc’s built-in field visuals.

```javascript theme={null}
new SuperDoc({
  selector: '#editor',
  document: 'contract.docx',
  modules: {
    contentControls: {
      chrome: 'none',
    },
  },
});
```

## Spell check

Provider-based spell check for the layout-engine editor surface. The configuration key is `proofing` because the provider contract is designed to support spelling, grammar, and style. The current UI renders spelling only.

```javascript theme={null}
new SuperDoc({
  selector: '#editor',
  document: 'contract.docx',
  proofing: {
    enabled: true,
    provider,
    defaultLanguage: 'en-US',
    maxSuggestions: 3,
  }
});
```

<Note>
  Bring your own provider. SuperDoc handles the editor UI. Your app controls the spell-check engine or API. See [Spell check](/editor/spell-check/overview) and [Custom spell-check provider](/editor/spell-check/custom-provider).
</Note>

<Info>
  Spell check runs when the layout engine is active. In `print` layout this works out of the box. In `web` layout, keep the layout engine enabled with `layoutEngineOptions.flowMode: 'semantic'`.
</Info>

<Note>
  Only spelling issues render in v1. Grammar and style issues can still be returned by your provider but are not shown yet.
</Note>

<ParamField path="proofing" type="Object">
  Spell-check configuration

  <Expandable title="properties" defaultOpen>
    <ParamField path="proofing.enabled" type="boolean" default="false">
      Enable or disable proofing
    </ParamField>

    <ParamField path="proofing.provider" type="Object">
      Provider instance with an `id` and `check()` function. When the provider returns `replacements`, SuperDoc shows them as direct context-menu actions.
    </ParamField>

    <ParamField path="proofing.defaultLanguage" type="string | null">
      Fallback language for segments without a resolved language
    </ParamField>

    <ParamField path="proofing.debounceMs" type="number" default="500">
      Debounce delay after edits before rechecking
    </ParamField>

    <ParamField path="proofing.maxSuggestions" type="number">
      Maximum replacement suggestions shown per issue
    </ParamField>

    <ParamField path="proofing.visibleFirst" type="boolean" default="true">
      Prioritize checking visible pages first
    </ParamField>

    <ParamField path="proofing.allowIgnoreWord" type="boolean" default="true">
      Show `Ignore` in the context menu
    </ParamField>

    <ParamField path="proofing.ignoredWords" type="string[]">
      Words to suppress from displayed proofing results. This is a SuperDoc-side suppression list, not a provider dictionary mutation.
    </ParamField>

    <ParamField path="proofing.timeoutMs" type="number" default="10000">
      Provider timeout per request in milliseconds
    </ParamField>

    <ParamField path="proofing.maxConcurrentRequests" type="number" default="2">
      Maximum number of provider requests in flight at the same time
    </ParamField>

    <ParamField path="proofing.maxSegmentsPerBatch" type="number" default="20">
      Maximum number of segments included in a single provider request
    </ParamField>

    <ParamField path="proofing.onProofingError" type="function">
      Called when the provider times out, returns invalid ranges, or fails
    </ParamField>

    <ParamField path="proofing.onStatusChange" type="function">
      Called with `idle`, `checking`, `disabled`, or `degraded`
    </ParamField>
  </Expandable>
</ParamField>

## Appearance

<ParamField path="title" type="string" default="'SuperDoc'">
  Document title for exports and display
</ParamField>

<ParamField path="colors" type="string[]">
  Colors for user awareness and highlighting
  <Note>Built-in palette provided by default</Note>
</ParamField>

<ParamField path="viewOptions" type="Object">
  Document view options for controlling layout

  <Expandable title="properties" defaultOpen>
    <ParamField path="viewOptions.layout" type="string" default="'print'">
      Document view layout mode

      * `'print'` - Fixed page width, displays document as it prints (default)
      * `'web'` - Content reflows to fit container width
    </ParamField>
  </Expandable>

  <Note>Use `'web'` for mobile devices and WCAG AA reflow compliance (Success Criterion 1.4.10). If you also need layout-engine-powered features such as proofing in web layout, set `layoutEngineOptions.flowMode: 'semantic'`.</Note>

  ```javascript theme={null}
  viewOptions: { layout: 'web' }
  ```
</ParamField>

<ParamField path="contained" type="boolean" default="false">
  Enable contained mode for fixed-height container embedding. When `true`, SuperDoc fits within its parent's height and scrolls internally instead of expanding to the document's natural height. Works with DOCX, PDF, and HTML documents.

  Use this when embedding SuperDoc inside a panel, sidebar, or any container with a fixed height (e.g., `height: 400px` or `flex: 1`).

  <CodeGroup>
    ```javascript Usage theme={null}
    const superdoc = new SuperDoc({
      selector: '#editor',
      document: file,
      contained: true,
    });
    ```

    ```html Full Example theme={null}
    <!-- Parent must have a definite height -->
    <div style="height: 500px;">
      <div id="editor"></div>
    </div>

    <script type="module">
      import { SuperDoc } from 'superdoc';
      import 'superdoc/style.css';

      new SuperDoc({
        selector: '#editor',
        document: yourFile,
        contained: true,
      });
    </script>
    ```
  </CodeGroup>
</ParamField>

<ParamField path="zoom" type="Object">
  Zoom behavior for the document. Use `mode: 'fit-width'` to keep DOCX and PDF documents fitted to the available container width. Calling `setZoom()` switches back to manual zoom.

  <Expandable title="properties" defaultOpen>
    <ParamField path="zoom.initial" type="number" default="100">
      Initial zoom level as a percentage. In `fit-width` mode, this is the paint zoom until the first fit computes.
    </ParamField>

    <ParamField path="zoom.mode" type="'manual' | 'fit-width'" default="'manual'">
      Starting zoom mode. `'manual'` holds the current value. `'fit-width'` keeps the document fitted to the container.
    </ParamField>

    <ParamField path="zoom.fitWidth" type="Object">
      Bounds and padding for the applied fit-width zoom.

      <Expandable title="properties">
        <ParamField path="zoom.fitWidth.min" type="number" default="10">
          Lower bound for the applied zoom percentage.
        </ParamField>

        <ParamField path="zoom.fitWidth.max" type="number" default="100">
          Upper bound for the applied zoom percentage. The default never enlarges the document past its natural size; raise it to let wide containers scale the page up.
        </ParamField>

        <ParamField path="zoom.fitWidth.padding" type="number" default="0">
          Horizontal padding in pixels reserved inside the available width before computing the fit.
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>

  For custom behavior, listen to [`viewport-change`](/editor/superdoc/events#viewport-change) and call `setZoom()` yourself.

  <CodeGroup>
    ```javascript Usage theme={null}
    const superdoc = new SuperDoc({
      selector: '#editor',
      document: file,
      zoom: {
        mode: 'fit-width',
        fitWidth: { min: 35, max: 100, padding: 24 },
      },
    });
    ```

    ```javascript Full Example theme={null}
    import { SuperDoc } from 'superdoc';
    import 'superdoc/style.css';

    const superdoc = new SuperDoc({
      selector: '#editor',
      document: yourFile,
      zoom: {
        initial: 100,
        mode: 'fit-width',
        fitWidth: { min: 35, max: 100, padding: 24 },
      },
      onZoomChange: ({ zoom, mode }) => {
        console.log(`Zoom is now ${zoom}% (${mode})`);
      },
    });
    ```
  </CodeGroup>

  <Card title="Responsive zoom example" icon="code" href="https://github.com/superdoc-dev/superdoc/tree/main/examples/editor/built-in-ui/responsive-zoom">
    Minimal React example for fit-width zoom with current zoom and viewport metrics.
  </Card>
</ParamField>

<ParamField path="layoutMode" type="string" deprecated>
  <Warning>**Removed in v1.0**: Use `viewOptions.layout` instead. `'paginated'` → `'print'`, `'responsive'` → `'web'`.</Warning>
</ParamField>

<ParamField path="layoutMargins" type="Object" deprecated>
  <Warning>**Removed in v1.0**: Use CSS to control margins in web layout mode.</Warning>
</ParamField>

<ParamField path="rulers" type="boolean" default="false">
  Show document rulers
</ParamField>

<ParamField path="toolbar" type="string">
  CSS selector for the built-in toolbar container (e.g. `'#toolbar'`). Shorthand for `modules.toolbar.selector`.

  Omit this to skip the built-in toolbar: for example, when using the [headless toolbar](/advanced/headless-toolbar) to build your own UI.
</ParamField>

## Advanced options

<ParamField path="editorExtensions" type="Extension[]" default="[]">
  Additional SuperDoc extensions
</ParamField>

<ParamField path="handleImageUpload" type="function">
  Custom image upload handler

  ```javascript theme={null}
  handleImageUpload: async (file) => {
    const formData = new FormData();
    formData.append('image', file);
    const response = await fetch('/upload', { 
      method: 'POST', 
      body: formData 
    });
    const { url } = await response.json();
    return url;
  }
  ```
</ParamField>

<ParamField path="telemetry" type="Object" deprecated>
  <Warning>**Deprecated since v1.8**: This option is no longer supported and will be ignored.</Warning>
</ParamField>

<ParamField path="jsonOverride" type="Object">
  Override document content with a JSON schema. Used to load documents from a previously exported JSON representation instead of a DOCX file.

  ```javascript theme={null}
  jsonOverride: { type: 'doc', content: [...] }
  ```
</ParamField>

<ParamField path="uiDisplayFallbackFont" type="string" default="'Arial, Helvetica, sans-serif'">
  Font family used for all SuperDoc UI elements (toolbar, comments, etc.)
</ParamField>

<ParamField path="suppressDefaultDocxStyles" type="boolean" default="false">
  Prevent default DOCX styles from being applied
</ParamField>

<ParamField path="disableContextMenu" type="boolean" default="false">
  Disable custom context menus
</ParamField>

<ParamField path="onUnsupportedContent" type="function">
  Callback invoked with HTML elements that were dropped during import because they have no schema representation. Receives an array of `{ tagName, outerHTML, count }` items. When provided, `console.warn` is suppressed.

  ```javascript theme={null}
  onUnsupportedContent: (items) => {
    items.forEach(({ tagName, count }) => {
      console.log(`Dropped ${count}x <${tagName}>`);
    });
  }
  ```
</ParamField>

<ParamField path="warnOnUnsupportedContent" type="boolean" default="false">
  Log a `console.warn` listing HTML elements dropped during import. Ignored when `onUnsupportedContent` is provided.
</ParamField>

<ParamField path="cspNonce" type="string">
  Content Security Policy nonce
</ParamField>

## Event handlers

All handlers are optional functions in the configuration:

<ParamField path="onReady" type="function">
  Called when SuperDoc is ready

  ```javascript theme={null}
  onReady: ({ superdoc }) => {
    console.log('Ready');
  }
  ```
</ParamField>

<ParamField path="onEditorBeforeCreate" type="function">
  Called before an editor is created
</ParamField>

<ParamField path="onEditorCreate" type="function">
  Called when editor is created

  ```javascript theme={null}
  onEditorCreate: ({ editor }) => {
    editor.focus();
  }
  ```
</ParamField>

<ParamField path="onEditorUpdate" type="function">
  Called on content changes

  ```javascript theme={null}
  onEditorUpdate: ({ editor }) => {
    autoSave(editor.getJSON());
  }
  ```
</ParamField>

<ParamField path="onZoomChange" type="function">
  Called when zoom changes from `setZoom()`, the toolbar zoom control, or `fit-width` mode.

  ```javascript theme={null}
  onZoomChange: ({ zoom, mode }) => {
    setZoomIndicator(zoom, mode);
  }
  ```
</ParamField>

<ParamField path="onViewportChange" type="function">
  Called when the fit-width calculation changes. Pixel-level width jitter is deduped. `getViewportMetrics()` always reads the latest measurements.

  ```javascript theme={null}
  onViewportChange: ({ availableWidth, documentWidth, fitZoom }) => {
    updateFitIndicator({ availableWidth, documentWidth, fitZoom });
  }
  ```
</ParamField>

<ParamField path="onTrackedChangeBubbleAccept" type="function">
  Custom handler for accepting tracked changes from comment bubbles. Replaces default accept behavior when provided.

  ```javascript theme={null}
  onTrackedChangeBubbleAccept: (comment, editor) => {
    // Custom logic before accepting
    editor.commands.acceptTrackedChangeById(comment.commentId);
    saveDocument(); // e.g., trigger auto-save after accept
  }
  ```

  <Note>Only fires from bubble buttons, not toolbar or context menu. The dialog cleanup (closing the bubble) happens automatically after your handler runs.</Note>

  <Warning>When using a custom handler, you are responsible for calling `editor.commands.acceptTrackedChangeById()` if you want the change accepted. The default behavior is fully replaced.</Warning>
</ParamField>

<ParamField path="onTrackedChangeBubbleReject" type="function">
  Custom handler for rejecting tracked changes from comment bubbles. Replaces default reject behavior when provided.

  ```javascript theme={null}
  onTrackedChangeBubbleReject: (comment, editor) => {
    // Custom logic before rejecting
    editor.commands.rejectTrackedChangeById(comment.commentId);
    logRejection(comment); // e.g., track rejections
  }
  ```

  <Note>Only fires from bubble buttons, not toolbar or context menu. The dialog cleanup (closing the bubble) happens automatically after your handler runs.</Note>

  <Warning>When using a custom handler, you are responsible for calling `editor.commands.rejectTrackedChangeById()` if you want the change rejected. The default behavior is fully replaced.</Warning>
</ParamField>

<ParamField path="onSidebarToggle" type="function">
  Called when the comments sidebar is toggled
</ParamField>

<ParamField path="onException" type="function">
  Called when an error occurs

  ```javascript theme={null}
  onException: ({ error }) => {
    console.error('SuperDoc error:', error);
  }
  ```
</ParamField>

See [Events](/editor/superdoc/events) for complete list.
