> ## Documentation Index
> Fetch the complete documentation index at: https://superdoc-caio-sd-2792-selection-active-ids.mintlify.site/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](/modules/track-changes) for accept/reject commands, the Document API, and configuration. The [runnable example](https://github.com/superdoc-dev/superdoc/tree/main/examples/features/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](/modules/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](/modules/collaboration/configuration) and [Collaboration guides](/modules/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="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>
  </Expandable>
</ParamField>

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

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](/modules/toolbar/built-in#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](/core/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](/core/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](/core/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](/modules/context-menu) for configuration options.</Warning>
</ParamField>

## Proofing

Provider-based spell check and proofing for the layout-engine editor surface.

```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, while your app controls the proofing engine or API. See [Proofing](/guides/general/proofing) and [Custom proofing provider](/guides/general/custom-proofing-provider).
</Note>

<Info>
  Proofing is available 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>
  In the current UI, only spelling issues are rendered. Grammar and style issues can still be returned by your provider, but they are not shown yet.
</Note>

<ParamField path="proofing" type="Object">
  Proofing 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="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](/modules/toolbar/headless) 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="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](/core/superdoc/events) for complete list.
