---
title: "Export .docx from your editor"
description: "Learn how to export Tiptap editor content to DOCX (Word) files using the Export extension in our docs."
canonical_url: "https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/editor-extension"
---

# Export .docx from your editor

Learn how to export Tiptap editor content to DOCX (Word) files using the Export extension in our docs.

- **1. Activate trial or subscribe**

  Start a [free trial](https://cloud.tiptap.dev/v2?trial=true) or [subscribe to the Start
  plan](https://cloud.tiptap.dev/v2/billing) in your account.
- **2. Install from private registry**

  To install this frontend extensions, authenticate to Tiptap’s private npm registry by following
  the [setup guide](https://tiptap-docs.lin52025i.qzz.io/guides/pro-extensions.md).

> **Interactive demo:** [ExportDocx](https://embed-pro.tiptap.dev/preview/Extensions/ExportDocx)

Use Tiptap’s `@tiptap-pro/extension-export-docx` to export the editor’s content as a `.docx` file. This extension works in any JavaScript environment, including server-side applications, due to the isomorphic nature of the `exportDocx` function.

You can also export via the [REST API](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/rest-api.md). Both paths use the same conversion library. The main differences:

|                       | Editor extension                                                                                                                                                                                                                                                                                                                                                                   | REST API                                                                                                                             |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| Runs in               | Your app (client or server-side)                                                                                                                                                                                                                                                                                                                                                   | Tiptap cloud                                                                                                                         |
| Custom node rendering | Supported via [`customNodes`](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/custom-nodes.md)                                                                                                                                                                                                                                                                         | Supported via [`customNodeDsl`](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/custom-nodes-dsl.md)\*                   |
| Element overrides     | [`paragraphOverrides`, `textRunOverrides`, `tableOverrides`, `tableRowOverrides`, `tableCellOverrides`, `imageOverrides`](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md#element-overrides), plus [`headerFooterOverrides`](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md#headerfooteroverrides) for header/footer-scoped overrides | Same fields as static objects, except `tableRowOverrides`\*                                                                          |
| Style overrides       | Supported                                                                                                                                                                                                                                                                                                                                                                          | Supported                                                                                                                            |
| Headers and footers   | docx.js objects or auto-extracted from Pages                                                                                                                                                                                                                                                                                                                                       | Plain text, stringified JSON, or a JSON object                                                                                       |
| Footnotes             | Auto-extracted from [Pages footnotes](https://tiptap-docs.lin52025i.qzz.io/pages/core-concepts/footnotes.md), or provided via the `footnotes` option                                                                                                                                                                                                                               | Provided via the [`footnotes` field](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/rest-api.md#footnotes-and-endnotes) |
| Endnotes              | Auto-extracted from [Pages endnotes](https://tiptap-docs.lin52025i.qzz.io/pages/core-concepts/endnotes.md), or provided via the `endnotes` option                                                                                                                                                                                                                                  | Provided via the [`endnotes` field](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/rest-api.md#footnotes-and-endnotes)  |

\* The REST API does not accept `customNodes` render functions or `tableRowOverrides`. Requests carrying them have those fields stripped during validation and the export proceeds with defaults. Use the editor extension if you need either.

Choose the REST API to export from your server without an editor. Use the editor extension when you need `customNodes` render functions, function-based overrides, `tableRowOverrides`, or full control over the output.

By default, the extension maps Tiptap nodes to DOCX elements. If your content includes custom nodes, configure their [export behavior](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/custom-nodes.md) to ensure they’re properly converted.

## Install the DOCX Export extension

The Conversion extensions are published in Tiptap’s private npm registry. Integrate the extensions by following the [private registry guide](https://tiptap-docs.lin52025i.qzz.io/guides/pro-extensions.md).

Once done you can install and import the **Export DOCX** extension package

```bash
npm i @tiptap-pro/extension-export-docx
```

Using the export extension does not require any Tiptap Conversion credentials, since the conversion is handled right away in the extension.

```js
import { ExportDocx } from '@tiptap-pro/extension-export-docx'
```

## Configuring the extension

The `ExportDocx` extension can be configured with an `ExportDocxOptions` (`object`) as an argument to the `configure` method with the following properties:

```ts
// Import the ExportDocx extension
import { ExportDocx } from '@tiptap-pro/extension-export-docx'

const editor = new Editor({
  extensions: [
    // Other extensions ...
    ExportDocx.configure({
      onCompleteExport: (result: string | Buffer<ArrayBufferLike> | Blob | Stream) => void, // required
      exportType: 'blob', // optional. Default: 'blob'
      customNodes: [], // optional. Default: []
      styleOverrides: {}, // optional. Default: {}
      paragraphOverrides: {}, // optional. Default: {}
      textRunOverrides: {}, // optional. Default: {}
      tableOverrides: {}, // optional. Default: {}
      tableRowOverrides: {}, // optional. Default: {}
      repeatTableHeaderRows: false, // optional. Default: false
      tableCellOverrides: {}, // optional. Default: {}
      imageOverrides: {}, // optional. Default: {}
      onWarning: undefined, // optional. Default: undefined
      onImageError: 'skip', // optional. Default: 'skip'
      numberingFormats: undefined, // optional. Default: undefined
      headerFooterOverrides: undefined, // optional. Default: undefined
      fonts: undefined, // optional. Default: undefined
      embedFonts: false, // optional. Default: false
      token: undefined, // optional. Default: undefined
      endpoint: undefined, // optional. Default: undefined
      region: 'eu', // optional. 'eu' or 'us'. Default: 'eu'
    }),
    // Other extensions ...
  ],
  // Other editor settings ...
})
```

| Parameter             | Description                                                                                                                                                                                                                                                                                                                                                                                                                                              | Default                   |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
| onCompleteExport      | A **required** callback function that receives the exported data. You can then handle the data as needed (e.g., prompt a file download)                                                                                                                                                                                                                                                                                                                  | `N/A`                     |
| options               | An object to configure some parts of the export:**exportType**: The type of data returned by the method:- **buffer**: Returns a Node.js `Buffer` (server-side only)- **stream**: Returns a Node.js `Stream` (server-side only)- **string**: Returns a `String`- **blob**: Returns a `Blob`                                                                                                                                                               | `blob`                    |
| customNodes           | An array of custom node definitions. If your content includes custom nodes, pass their definitions here to ensure they're properly converted                                                                                                                                                                                                                                                                                                             | `[]`                      |
| styleOverrides        | An object with custom styles to apply to the exported document. [See Export styles](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md)                                                                                                                                                                                                                                                                                               | `{}`                      |
| paragraphOverrides    | Base defaults for all paragraphs (also applied to header/footer content). Accepts a static object applied to every paragraph, or a function `(node) => overrides` that receives the current paragraph node. [See Element overrides](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md#element-overrides)                                                                                                                             | `{}`                      |
| textRunOverrides      | Base defaults for all text runs (also applied to header/footer content). Accepts a static object applied to every text run, or a function `(node) => overrides` that receives the current text node. [See Element overrides](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md#element-overrides)                                                                                                                                    | `{}`                      |
| tableOverrides        | Table-level property overrides (also applied to header/footer tables). Accepts a static object applied to every table, or a function `(node) => overrides` that receives the current table node. [See Element overrides](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md#element-overrides)                                                                                                                                        | `{}`                      |
| tableRowOverrides     | Base defaults for all table rows (e.g. `cantSplit`, `tableHeader`, `height`; also applied to header/footer tables). Accepts a static object applied to every row, or a function `(node) => overrides` that receives the current table row node. [See Element overrides](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md#element-overrides)                                                                                         | `{}`                      |
| repeatTableHeaderRows | Repeat the rows of header cells at the top of each table on every page, like Word's "Repeat as header row". A `tableHeader` from `tableRowOverrides` still wins. [See Tables](https://tiptap-docs.lin52025i.qzz.io/conversion/content-types/structures-and-media/tables.md#export)                                                                                                                                                                       | `false`                   |
| tableCellOverrides    | Base defaults for all table cells (also applied to header/footer cells). Accepts a static object applied to every cell, or a function `(node) => overrides` that receives the current table cell node. [See Element overrides](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md#element-overrides)                                                                                                                                  | `{}`                      |
| imageOverrides        | Image property overrides (also applied to images in headers/footers). Accepts either a static object applied to every image, or a function `(node) => overrides` that receives the current image node so overrides can be derived from its attributes. [See Element overrides](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md#element-overrides)                                                                                  | `{}`                      |
| onWarning             | Called for each image the export skipped, with `code`, `message` and `src`. Without it, skipped images go to `console.warn`. [See Images that cannot be exported](#images-that-cannot-be-exported)                                                                                                                                                                                                                                                       | `undefined`               |
| onImageError          | What to do with an image the exporter cannot use. `skip` leaves it out and reports it; `throw` fails the whole export. [See Images that cannot be exported](#images-that-cannot-be-exported)                                                                                                                                                                                                                                                             | `'skip'`                  |
| numberingFormats      | Registry of multilevel ordered-list numbering format definitions. Each entry's `id` matches the `numberingFormat` attribute on the outermost `<ol>`; unknown / missing ids fall back to plain `1. 2. 3.` numbering. Pair this with `OrderedListNumbering` and `generateNumberingFormatCss` from `@tiptap-pro/extension-convert-kit`. [See Ordered list numbering](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/ordered-list-numbering.md) | `undefined`               |
| headerFooterOverrides | Per-field overrides scoped to header/footer content only; they fully replace the matching body-wide override inside headers and footers. Only applies to headers/footers auto-extracted from the [Pages extension](https://tiptap-docs.lin52025i.qzz.io/pages/getting-started/overview.md). [See `headerFooterOverrides`](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md#headerfooteroverrides)                                   | `undefined`               |
| footnotes             | Footnote content keyed by note id (`Record<string, JSONContent>`). Each `footnoteReference` node in the body whose `noteId` has an entry exports as a real Word footnote. Auto-extracted from [Pages footnotes](https://tiptap-docs.lin52025i.qzz.io/pages/core-concepts/footnotes.md) when enabled; pass this option only to override.                                                                                                                  | Auto-extracted from Pages |
| endnotes              | Endnote content keyed by note id (`Record<string, JSONContent>`). Each `endnoteReference` node in the body whose `noteId` has an entry exports as a real Word endnote. Auto-extracted from [Pages endnotes](https://tiptap-docs.lin52025i.qzz.io/pages/core-concepts/endnotes.md) when enabled; pass this option only to override.                                                                                                                       | Auto-extracted from Pages |
| fonts                 | Custom TTF/OTF fonts to embed so the file renders with the intended fonts even on machines where they aren't installed. [See Fonts](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/fonts.md)                                                                                                                                                                                                                                                | `undefined`               |
| embedFonts            | Automatically detect the fonts the document uses, locate them via the page's `@font-face` rules (with a Google Fonts fallback), convert WOFF2 to TTF through the Convert Service, and embed them. Browser only. [See Fonts](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/fonts.md)                                                                                                                                                        | `false`                   |
| token                 | Tiptap Convert JWT, sent only when `embedFonts` needs to convert a WOFF2 font. [See Fonts](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/fonts.md)                                                                                                                                                                                                                                                                                         | `undefined`               |
| endpoint              | Tiptap Convert REST endpoint base used for WOFF2 → TTF conversion. When set, it overrides `region`. [See Fonts](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/fonts.md)                                                                                                                                                                                                                                                                    | `undefined`               |
| region                | Tiptap Cloud region used for WOFF2 → TTF conversion when `endpoint` is not set, `'eu'` or `'us'`. [See Fonts](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/fonts.md)                                                                                                                                                                                                                                                                      | `'eu'`                    |

> **Page-number token names are configured on Pages, not here:**
>
> There is no `placeholders` option on `ExportDocx`. To rename the built-in `{page}` / `{total}`
> tokens or disable substitution, configure it on the [Pages
> extension](https://tiptap-docs.lin52025i.qzz.io/pages/core-concepts/page-header-footer.md#renaming-or-disabling-placeholders). The export
> honors the same token names, so the editor preview and the exported `.docx` stay consistent.

## Export a DOCX file

With the extension installed, you can convert your editor’s content to `.docx`.

Before diving into an example, let's take a look into the signature of the `exportDocx` method available in your editor's commands:

```ts
/**
 * Export the current document as a .docx file
 *
 * Notes: 'buffer' and 'stream' export types are only available in the server environment
 * as they use the Node Buffer and Stream APIs respectively
 *
 * @param onCompleteExport - Callback function to handle the exported file
 * @param options - Export options
 * @param customNodes - Custom node definitions to ensure proper conversion
 * @param styleOverrides - Custom styles to apply to the exported document
 * @example editor.commands.exportDocx((result) => {}, { exportType: 'buffer' }, [])
 *
 */
exportDocx: (options?: ExportDocxOptions) =>
  Promise<string | Buffer<ArrayBufferLike> | Blob | Stream>
```

The `exportDocx` method takes an optional `ExportDocxOptions` (`object`) as an argument with the following properties that you can use to *override* the ones that you have configured with the `ExportDocx.configure` method:

| Parameter             | Description                                                                                                                                                                                                                                                                                                                                                                                                                                              | Default                   |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
| onCompleteExport      | A **required** callback function (if you haven't defined it in the configure extension call) that receives the exported data. You can then handle the data as needed (e.g., prompt a file download)                                                                                                                                                                                                                                                      | `N/A`                     |
| options               | An object to configure some parts of the export:**exportType**: The type of data returned by the method:- **buffer**: Returns a Node.js `Buffer` (server-side only)- **stream**: Returns a Node.js `Stream` (server-side only)- **string**: Returns a `String`- **blob**: Returns a `Blob`                                                                                                                                                               | `blob`                    |
| customNodes           | An array of custom node definitions. If your content includes custom nodes, pass their definitions here to ensure they're properly converted                                                                                                                                                                                                                                                                                                             | `[]`                      |
| styleOverrides        | An object with custom styles to apply to the exported document. [See Export styles](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md)                                                                                                                                                                                                                                                                                               | `{}`                      |
| paragraphOverrides    | Base defaults for all paragraphs (also applied to header/footer content). Accepts a static object applied to every paragraph, or a function `(node) => overrides` that receives the current paragraph node. [See Element overrides](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md#element-overrides)                                                                                                                             | `{}`                      |
| textRunOverrides      | Base defaults for all text runs (also applied to header/footer content). Accepts a static object applied to every text run, or a function `(node) => overrides` that receives the current text node. [See Element overrides](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md#element-overrides)                                                                                                                                    | `{}`                      |
| tableOverrides        | Table-level property overrides (also applied to header/footer tables). Accepts a static object applied to every table, or a function `(node) => overrides` that receives the current table node. [See Element overrides](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md#element-overrides)                                                                                                                                        | `{}`                      |
| tableRowOverrides     | Base defaults for all table rows (e.g. `cantSplit`, `tableHeader`, `height`; also applied to header/footer tables). Accepts a static object applied to every row, or a function `(node) => overrides` that receives the current table row node. [See Element overrides](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md#element-overrides)                                                                                         | `{}`                      |
| repeatTableHeaderRows | Repeat the rows of header cells at the top of each table on every page, like Word's "Repeat as header row". A `tableHeader` from `tableRowOverrides` still wins. [See Tables](https://tiptap-docs.lin52025i.qzz.io/conversion/content-types/structures-and-media/tables.md#export)                                                                                                                                                                       | `false`                   |
| tableCellOverrides    | Base defaults for all table cells (also applied to header/footer cells). Accepts a static object applied to every cell, or a function `(node) => overrides` that receives the current table cell node. [See Element overrides](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md#element-overrides)                                                                                                                                  | `{}`                      |
| imageOverrides        | Image property overrides (also applied to images in headers/footers). Accepts either a static object applied to every image, or a function `(node) => overrides` that receives the current image node so overrides can be derived from its attributes. [See Element overrides](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md#element-overrides)                                                                                  | `{}`                      |
| onWarning             | Called for each image the export skipped, with `code`, `message` and `src`. Without it, skipped images go to `console.warn`. [See Images that cannot be exported](#images-that-cannot-be-exported)                                                                                                                                                                                                                                                       | `undefined`               |
| onImageError          | What to do with an image the exporter cannot use. `skip` leaves it out and reports it; `throw` fails the whole export. [See Images that cannot be exported](#images-that-cannot-be-exported)                                                                                                                                                                                                                                                             | `'skip'`                  |
| numberingFormats      | Registry of multilevel ordered-list numbering format definitions. Each entry's `id` matches the `numberingFormat` attribute on the outermost `<ol>`; unknown / missing ids fall back to plain `1. 2. 3.` numbering. Pair this with `OrderedListNumbering` and `generateNumberingFormatCss` from `@tiptap-pro/extension-convert-kit`. [See Ordered list numbering](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/ordered-list-numbering.md) | `undefined`               |
| headerFooterOverrides | Per-field overrides scoped to header/footer content only; they fully replace the matching body-wide override inside headers and footers. Only applies to headers/footers auto-extracted from the [Pages extension](https://tiptap-docs.lin52025i.qzz.io/pages/getting-started/overview.md). [See `headerFooterOverrides`](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/styles.md#headerfooteroverrides)                                   | `undefined`               |
| footnotes             | Footnote content keyed by note id (`Record<string, JSONContent>`). Each `footnoteReference` node in the body whose `noteId` has an entry exports as a real Word footnote. Auto-extracted from [Pages footnotes](https://tiptap-docs.lin52025i.qzz.io/pages/core-concepts/footnotes.md) when enabled; pass this option only to override.                                                                                                                  | Auto-extracted from Pages |
| endnotes              | Endnote content keyed by note id (`Record<string, JSONContent>`). Each `endnoteReference` node in the body whose `noteId` has an entry exports as a real Word endnote. Auto-extracted from [Pages endnotes](https://tiptap-docs.lin52025i.qzz.io/pages/core-concepts/endnotes.md) when enabled; pass this option only to override.                                                                                                                       | Auto-extracted from Pages |
| fonts                 | Custom TTF/OTF fonts to embed so the file renders with the intended fonts even on machines where they aren't installed. [See Fonts](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/fonts.md)                                                                                                                                                                                                                                                | `undefined`               |
| embedFonts            | Automatically detect the fonts the document uses, locate them via the page's `@font-face` rules (with a Google Fonts fallback), convert WOFF2 to TTF through the Convert Service, and embed them. Browser only. [See Fonts](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/fonts.md)                                                                                                                                                        | `false`                   |
| token                 | Tiptap Convert JWT, sent only when `embedFonts` needs to convert a WOFF2 font. [See Fonts](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/fonts.md)                                                                                                                                                                                                                                                                                         | `undefined`               |
| endpoint              | Tiptap Convert REST endpoint base used for WOFF2 → TTF conversion. When set, it overrides `region`. [See Fonts](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/fonts.md)                                                                                                                                                                                                                                                                    | `undefined`               |
| region                | Tiptap Cloud region used for WOFF2 → TTF conversion when `endpoint` is not set, `'eu'` or `'us'`. [See Fonts](https://tiptap-docs.lin52025i.qzz.io/conversion/export/docx/fonts.md)                                                                                                                                                                                                                                                                      | `'eu'`                    |

```js
// Import the ExportDocx extension
import { ExportDocx } from '@tiptap-pro/extension-export-docx'

// Setup you editor
const editor = new Editor({
  extensions: [
    // Other extensions ...
    ExportDocx.configure({
      onCompleteExport: (result: string | Buffer<ArrayBufferLike> | Blob | Stream) => {}, // required
      exportType: 'blob', // optional. Default: 'blob'
      customNodes: [], // optional. Default: []
      styleOverrides: {}, // optional. Default: {}
      paragraphOverrides: {}, // optional. Default: {}
      textRunOverrides: {}, // optional. Default: {}
      tableOverrides: {}, // optional. Default: {}
      tableRowOverrides: {}, // optional. Default: {}
      repeatTableHeaderRows: false, // optional. Default: false
      tableCellOverrides: {}, // optional. Default: {}
      imageOverrides: {}, // optional. Default: {}
      onWarning: undefined, // optional. Default: undefined
      onImageError: 'skip', // optional. Default: 'skip'
      headerFooterOverrides: undefined, // optional. Default: undefined
      fonts: undefined, // optional. Default: undefined
      embedFonts: false, // optional. Default: false
      token: undefined, // optional. Default: undefined
      endpoint: undefined, // optional. Default: undefined
      region: 'eu', // optional. 'eu' or 'us'. Default: 'eu'
    }),
    // Other extensions ...
  ],
  // Other editor settings ...
})

// Declare some functions that will call the exportDocx method from your editor

function handleExportDocx() {
  // Call your editor's exportDocx method
  editor
    .chain()
    // Method call without any overrides
    // It will take the configuration set in the configure method
    .exportDocx()
    .run()
}

function handleExportDocxBuffer() {
  // Call your editor's exportDocx method
  editor
    .chain()
    // Method call with some overrides
    .exportDocx({
      // Override the onCompleteExport callback to handle the override exported type
      onCompleteExport: (result: Buffer) => {
        // Handle the exported file in a buffer format
      },
      // Override the export type
      exportType: 'Buffer',
    })
    .run()
}

// Call those functions at any point in your application
handleExportDocx()
handleExportDocxBuffer()
```

### How it works

The above example runs entirely in the browser, generating a DOCX Blob via the ExportDocx extension since it's the default value for the `exportType` as we haven't override it. We then programmatically download the file. You can adjust this logic, for instance, to send the blob to a server instead of downloading.

| Parameter        | Description                                                                                                                                                                                                                                                                                                                                                                                     |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| onCompleteExport | When the conversion completes, we will get the `result` of the conversion as the main and only argument to the callback function which, in this case, it would be a `Blob` since we've declared that we wanted this type in the `exportType` within the `options` parameter. You can then handle it however you prefer, e.g. prompting a file download, like we showcased in the example above. |
| exportType       | We're using the default `blob` so the conversion returns a `Blob`.                                                                                                                                                                                                                                                                                                                              |
| customNodes      | We won't provide any custom node mapping since we are not providing any custom nodes.                                                                                                                                                                                                                                                                                                           |
| styleOverrides   | We won't provide any style overrides, and therefore, a default `DOCX` style is set following some common guideliness from Microsoft Word defaults and they will be applied to the exported document.                                                                                                                                                                                            |

## Server-side export

For applications requiring complex document generation or to reduce client-side bundle size, you can export `.docx` files in your the server.

In order to do so, you'd need to import the `exportDocx` function from the `@tiptap-pro/extension-export-docx` package, pass it your Tiptap JSON content, and return the resulting conversion to the client.

Let's first take a look into the `exportDocx` function signature:

```ts
/**
 * Export the current document as a .docx file
 *
 * Notes: 'buffer' and 'stream' export types are only available in the server environment
 * as they use the Node Buffer and Stream APIs respectively
 *
 * @param options.document - The JSON representation of the document
 * @param options.exportType - The type of export to perform
 * @param options.customNodes - Custom node definitions
 * @param options.styleOverrides - Style overrides for the exported document
 * @param options.paragraphOverrides - Base defaults for all paragraphs
 * @param options.textRunOverrides - Base defaults for all text runs
 * @param options.tableOverrides - Table-level property overrides
 * @param options.tableRowOverrides - Base defaults for all table rows
 * @param options.tableCellOverrides - Base defaults for all table cells
 * @param options.imageOverrides - Image property overrides
 * @param options.onWarning - Called for each image the export skipped
 * @param options.onImageError - 'skip' (default) or 'throw'
 * @example exportDocx({ document: editor.getJSON(), exportType: 'blob', customNodes: [], styleOverrides: {} })
 */
async function exportDocx({
  document,
  exportType,
  customNodes,
  styleOverrides,
  paragraphOverrides,
  textRunOverrides,
  tableOverrides,
  tableRowOverrides,
  tableCellOverrides,
  imageOverrides,
  onWarning,
  onImageError,
}: ExportDocxOptions) {}
```

The `exportDocx` function will return a `docx` document ready and converted to any format that .

Here you have a simple example using `Express` and `@tiptap-pro/extension-export-docx` on the server-side:

```ts
import { exportDocx } from '@tiptap-pro/extension-export-docx'
import express from 'express'

const app = express()

app.post('/export-docx', async (req, res) => {
  try {
    // Get Tiptap JSON content from the request or from your database
    const { content } = req.body

    // Convert Tiptap JSON to DOCX
    const docxBuffer = await exportDocx({ document: content })

    // Send as a downloadable file
    res.setHeader(
      'Content-Type',
      'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    )
    res.setHeader('Content-Disposition', 'attachment; filename="document.docx"')
    res.send(docxBuffer)
  } catch (error) {
    res.status(500).json({ error: error.message })
  }
})
```

## Images that cannot be exported

The export fetches every image by its `src`. Some cannot be used: the URL returns a 404,
the host does not answer, or the format is one DOCX cannot embed. Word writes EMF for
pasted charts and equations, so documents that came from Word often carry one.

By default the export leaves that image out and carries on, so one broken picture does not
cost you the whole file. If the image was the only thing in its paragraph, the paragraph
goes too, leaving no blank line behind.

Pass `onWarning` to find out which images were skipped:

```js
ExportDocx.configure({
  onCompleteExport: result => saveAs(result, 'export.docx'),
  onWarning: warning => {
    console.log(warning.code, warning.src)
  },
})
```

Each warning carries:

| Field         | Description                                                                                    |
| ------------- | ---------------------------------------------------------------------------------------------- |
| `code`        | `image-missing-src`, `image-request-failed`, `image-fetch-failed`, or `image-unsupported-type` |
| `message`     | Readable summary, safe to log                                                                  |
| `src`         | The image URL, when the node had one                                                           |
| `status`      | HTTP status, when the host answered with a failure                                             |
| `contentType` | The detected type, for an unsupported format                                                   |

Without `onWarning`, skipped images are reported through `console.warn`. Exceptions thrown
inside `onWarning` are swallowed, so a mistake in your handler cannot break an export.

To fail the export instead, set `onImageError: 'throw'`. The thrown error is one of
`ImageMissingSrcError`, `ImageRequestError`, `ImageFetchError` or `UnsupportedImageTypeError`,
all exported from the package and all extending `ImageConversionError`:

```js
import { ImageConversionError } from '@tiptap-pro/extension-export-docx'

try {
  await exportDocx({ document, onImageError: 'throw' })
} catch (error) {
  if (error instanceof ImageConversionError) {
    console.log(`Could not use ${error.src}: ${error.code}`)
  }
}
```

> **Relative image URLs are not resolved:**
>
> Export runs against the `src` exactly as stored. A relative URL such as `/img/chart.png` has
> no origin to resolve against, so it is reported as `image-request-failed` and skipped. Store
> absolute URLs the exporter can reach.

## Node attribute inference

The DOCX export automatically respects node-level attributes set by the editor, rather than always computing values from scratch. This means resized images, adjusted table columns, and other editor-level customizations are preserved in the exported document.

| Feature                                        | Description                                                                                                                                                                                                                |
| ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Image `width`/`height`**                     | When an image has been resized in the editor, the user-set dimensions are used. Priority: `imageOverrides.transformation` > `node.attrs.width/height` > intrinsic dimensions                                               |
| **Image `alt` text**                           | Mapped to the docx `altText` property for accessibility metadata                                                                                                                                                           |
| **Table cell `colwidth`**                      | Per-cell pixel array from editor-resized columns produces precise column widths in the export. On a fluid table the columns keep their proportions                                                                         |
| **Table cell `rowspan`**                       | Cells spanning multiple rows are correctly exported                                                                                                                                                                        |
| **Table `width`**                              | A table with an explicit `width` exports at that fixed width; a table with no width exports full width (fluid) so it reflows to the page                                                                                   |
| **Table borders**                              | The table's own borders (outer edges plus the inside horizontal and vertical grid) are exported; a borderless table stays borderless                                                                                       |
| **Table cell `background`**                    | Exported as cell shading                                                                                                                                                                                                   |
| **Table cell borders**                         | Per-side cell borders (`width` / `style` / `color`) are exported; a cell border that differs from the table's is kept as an override                                                                                       |
| **Table cell `verticalAlign`**                 | `top` / `middle` / `bottom` exported as the cell vertical alignment                                                                                                                                                        |
| **Table row `height` / `heightRule`**          | Row height is exported; `exact` clips to the height, `atLeast` treats it as a minimum                                                                                                                                      |
| **Table cell margins**                         | `cellMarginTop` / `cellMarginRight` / `cellMarginBottom` / `cellMarginLeft` on the table node are exported as the table's cell margins. A table without them uses Word's default                                           |
| **Paragraph `textAlign: 'justify'`**           | Correctly mapped to `AlignmentType.JUSTIFIED` (previously fell through to left alignment)                                                                                                                                  |
| **Text run `backgroundColor`**                 | `textStyle` mark `backgroundColor` exported as solid character shading                                                                                                                                                     |
| **Paragraph/heading `lineHeight`**             | Proportional line height (a unitless multiple such as `1.5` or a percentage such as `150%`) is written as a relative line that scales with the font size. A fixed `px`/`pt` line height is written as an exact line height |
| **Paragraph/heading spacing**                  | `spacingBefore` and `spacingAfter` are written as space before/after the paragraph                                                                                                                                         |
| **Paragraph/heading indentation**              | `indent`, `indentRight`, and `firstLineIndent` are written as left, right, and first-line indentation; a negative `firstLineIndent` becomes a hanging indent                                                               |
| **Paragraph/heading `contextualSpacing`**      | Suppresses spacing between adjacent paragraphs of the same style in the export                                                                                                                                             |
| **Paragraph/heading `keepNext` / `keepLines`** | Written as Word's keep-with-next and keep-lines-together pagination hints                                                                                                                                                  |

## What to expect

- **No authentication required.** The export runs entirely in the browser (or your Node.js server using the same package). No token, no API call.
- **Browser and server-side environments are both supported** via the same package. The server-side example above shows the Node.js path; the browser path is the default.
- **Synchronous result delivery.** The `onCompleteExport` callback receives the exported file directly, as a `Blob`, `Buffer`, `Stream`, or `string` depending on `exportType`.

## What not to expect

- **Round-trip identity.** Importing a DOCX, editing it, and exporting it back is not byte-identical. A handful of attributes (tab stops, and fixed `px`/`pt` line heights) are extracted on import but not written on export today. See the [feature support matrix](https://tiptap-docs.lin52025i.qzz.io/conversion/getting-started/feature-support-matrix.md) for the full list.
- **Pixel-perfect Word match.** We aim for visually faithful round-trips on the supported feature set; absolute parity with Word's rendering engine is out of scope.
- **Page layout from the editor.** DOCX export preserves headers, footers, and page-format settings you configure on the export options. It does not infer page boundaries from on-screen pagination, so pair it with the [Pages extension](https://tiptap-docs.lin52025i.qzz.io/pages/getting-started/overview.md) when you need pagination-aware exports.

## Support & Limitations

For a detailed breakdown of which document features are supported at each stage of the pipeline, see the [Supported features](https://tiptap-docs.lin52025i.qzz.io/conversion/getting-started/feature-support-matrix.md) matrix.
