# How to Export Editor Content to Word (.docx) in React Tiptap Editor

> Easily export React Tiptap editor content to Word (.docx) format. Learn how the ExportWord extension serializes content and triggers a browser download for seamless document integration.

- Repository: [Hung Hoang/reactjs-tiptap-editor](https://github.com/hunghg255/reactjs-tiptap-editor)
- Tags: how-to-guide
- Published: 2026-03-03

---

**The `ExportWord` extension in `reactjs-tiptap-editor` exposes an `exportToWord` command that serializes the ProseMirror document into a Word-compatible `.docx` file and triggers an automatic browser download.**

The `hunghg255/reactjs-tiptap-editor` repository provides a dedicated solution for converting Tiptap editor content to Microsoft Word format. By leveraging the `prosemirror-docx` library alongside the `docx` npm package, this extension traverses the editor's node tree and generates properly formatted Word documents with support for tables, text styling, and line breaks.

## How the ExportWord Extension Works

The export process follows a four-step pipeline implemented across several source files. Understanding this flow helps you debug issues or extend the functionality for custom node types.

### Extension Registration

In [`src/extensions/ExportWord/ExportWord.ts`](https://github.com/hunghg255/reactjs-tiptap-editor/blob/main/src/extensions/ExportWord/ExportWord.ts), the extension registers the `exportToWord` command within the Tiptap editor ecosystem. When initialized, it accepts the current editor state (`doc`) and makes the export functionality available through the editor's command chain.

### Document Serialization

The core conversion logic uses `DocxSerializer` from `prosemirror-docx` to walk the ProseMirror node tree. The extension defines custom node serializers in the same file to handle specific formatting:

- **Tables** are configured to occupy 100% page width using `WidthType.PERCENTAGE` (lines 32-40)
- **Line breaks** and paragraph spacing preserve the document structure
- **Images** currently render as inline placeholders only, as binary embedding requires additional `ArrayBuffer` conversion via `getImageBuffer`

### Blob Generation and Download

After serialization, the `Document` object from the `docx` library is converted to a binary Blob using `Packer.toBlob`. The helper function `downloadFromBlob` in [`src/utils/download.ts`](https://github.com/hunghg255/reactjs-tiptap-editor/blob/main/src/utils/download.ts) creates a temporary object URL and programmatically clicks an invisible anchor element, saving the file as `richtext-export-document.docx` by default.

### UI Integration

The `RichTextExportWord` component in [`src/extensions/ExportWord/components/RichTextExportWord.tsx`](https://github.com/hunghg255/reactjs-tiptap-editor/blob/main/src/extensions/ExportWord/components/RichTextExportWord.tsx) provides the toolbar button. It consumes the button configuration via `useButtonProps` and invokes the `exportToWord` command when clicked, as demonstrated in the playground at [`playground/src/App.tsx`](https://github.com/hunghg255/reactjs-tiptap-editor/blob/main/playground/src/App.tsx).

## Implementation Guide

Integrating Word export capability requires three steps: importing the extension, adding it to your editor configuration, and rendering the trigger button.

### 1. Import the ExportWord Extension

Import the extension from the dedicated export path to enable the serialization logic.

```typescript
import { ExportWord } from 'reactjs-tiptap-editor/exportword';

```

### 2. Configure Your Editor

Add `ExportWord` to your extensions array when initializing the Tiptap editor. The extension automatically registers the necessary commands and serializers.

```typescript
import { useEditor } from '@tiptap/react';
import { Document } from '@tiptap/extension-document';
import { Paragraph } from '@tiptap/extension-paragraph';
import { Text } from '@tiptap/extension-text';
import { ExportWord } from 'reactjs-tiptap-editor/exportword';

const editor = useEditor({
  extensions: [
    Document,
    Paragraph,
    Text,
    ExportWord,  // Enables .docx export functionality
  ],
  content: '<p>Your initial content here</p>',
});

```

### 3. Add the Export Button to Your Toolbar

Place the `RichTextExportWord` component in your toolbar or action bar to provide the user interface for triggering the download.

```tsx
import { RichTextExportWord } from 'reactjs-tiptap-editor/exportword';

function Toolbar() {
  return (
    <div className="flex gap-2">
      {/* Other toolbar items */}
      <RichTextExportWord />  {/* Click to download .docx */}
    </div>
  );
}

```

### 4. Complete Working Example

The following example from [`playground/src/App.tsx`](https://github.com/hunghg255/reactjs-tiptap-editor/blob/main/playground/src/App.tsx) demonstrates a minimal implementation connecting all pieces together.

```tsx
import { useEditor, EditorContent } from '@tiptap/react';
import { Document } from '@tiptap/extension-document';
import { Paragraph } from '@tiptap/extension-paragraph';
import { Text } from '@tiptap/extension-text';
import { ExportWord } from 'reactjs-tiptap-editor/exportword';
import { RichTextExportWord } from 'reactjs-tiptap-editor/exportword';

export default function App() {
  const editor = useEditor({
    extensions: [Document, Paragraph, Text, ExportWord],
    content: '<p>Export this content to Word format</p>',
  });

  return (
    <>
      <RichTextExportWord />
      <EditorContent editor={editor} />
    </>
  );
}

```

## Technical Details and Limitations

When implementing Word export in production applications, consider these implementation specifics from the source code.

### Image Handling Constraints

The current implementation in [`ExportWord.ts`](https://github.com/hunghg255/reactjs-tiptap-editor/blob/main/ExportWord.ts) deliberately skips image embedding. The `image` serializer calls `state.renderInline(node)` to create a placeholder rather than embedding binary data. To support embedded images, extend the serializer to utilize the `getImageBuffer` helper, which fetches image URLs and returns `Uint8Array` data suitable for the `docx` library.

### Table Formatting

Tables automatically expand to full page width (`width: { size: 100, type: WidthType.PERCENTAGE }`) to prevent content shrinking or collapsing in Word. This behavior is hardcoded in the table node serializer to ensure consistent Word document layouts regardless of browser rendering differences.

### Source File Reference

These files contain the implementation details referenced throughout this guide:

- **[`src/extensions/ExportWord/ExportWord.ts`](https://github.com/hunghg255/reactjs-tiptap-editor/blob/main/src/extensions/ExportWord/ExportWord.ts)** – Core extension logic, command definition, and node serializers
- **[`src/extensions/ExportWord/components/RichTextExportWord.tsx`](https://github.com/hunghg255/reactjs-tiptap-editor/blob/main/src/extensions/ExportWord/components/RichTextExportWord.tsx)** – React toolbar button component
- **[`src/utils/download.ts`](https://github.com/hunghg255/reactjs-tiptap-editor/blob/main/src/utils/download.ts)** – Browser download helper using Blob URLs
- **[`playground/src/App.tsx`](https://github.com/hunghg255/reactjs-tiptap-editor/blob/main/playground/src/App.tsx)** – Real-world integration example

## Summary

- **Enable the extension** by importing `ExportWord` from `reactjs-tiptap-editor/exportword` and adding it to your Tiptap extensions array.
- **Trigger downloads** via the `exportToWord` command, which uses `prosemirror-docx` to serialize the ProseMirror document into a `docx` library `Document` object.
- **Use the UI component** `RichTextExportWord` to provide a ready-made toolbar button that wires into the export command.
- **Handle limitations** by noting that images export as placeholders only, and tables default to 100% width to maintain layout integrity.
- **Reference key files** in `src/extensions/ExportWord/` and [`src/utils/download.ts`](https://github.com/hunghg255/reactjs-tiptap-editor/blob/main/src/utils/download.ts) for customization or debugging.

## Frequently Asked Questions

### Can I export images to the Word document?

Currently, the `ExportWord` extension renders images as inline placeholders only. The source code in [`src/extensions/ExportWord/ExportWord.ts`](https://github.com/hunghg255/reactjs-tiptap-editor/blob/main/src/extensions/ExportWord/ExportWord.ts) intentionally skips binary embedding to avoid complexity. However, the codebase includes a `getImageBuffer` utility that fetches image URLs as `ArrayBuffer` objects. You can extend the node serializer to utilize these buffers and embed `Uint8Array` data into the Word document if your use case requires image support.

### How do I customize the filename of the exported document?

The default filename is `richtext-export-document.docx`, defined in the `exportToWord` command within [`ExportWord.ts`](https://github.com/hunghg255/reactjs-tiptap-editor/blob/main/ExportWord.ts). To customize this, you would need to fork or patch the extension to pass a custom filename parameter to the `downloadFromBlob` helper in [`src/utils/download.ts`](https://github.com/hunghg255/reactjs-tiptap-editor/blob/main/src/utils/download.ts), which currently creates the download link with a hardcoded or default name.

### Why do tables appear at 100% width in the exported file?

The serializer enforces full-width tables (`WidthType.PERCENTAGE` with size 100) in lines 32-40 of [`ExportWord.ts`](https://github.com/hunghg255/reactjs-tiptap-editor/blob/main/ExportWord.ts) to prevent table content from shrinking or collapsing in Word. This ensures consistent rendering across different Word versions and screen sizes, regardless of the table's appearance in the browser editor.

### Does this extension support all Tiptap node types?

The extension supports standard text nodes, paragraphs, headings, and tables through the custom `nodeSerializer` configuration. Complex or custom node types may require additional serializers in [`ExportWord.ts`](https://github.com/hunghg255/reactjs-tiptap-editor/blob/main/ExportWord.ts) to map ProseMirror nodes to their `docx` library equivalents. Unsupported nodes will be skipped or rendered as plain text during serialization.