🚀 BlockNote AI is here! Access the early preview.
BlockNote Docs/Features/Export/DOCX

DOCX

It's possible to export BlockNote documents to docx, completely client-side.

This feature is provided by the @blocknote/xl-docx-exporter. xl- packages are fully open source, but released under a copyleft license. A commercial license for usage in closed source, proprietary products comes as part of the Business subscription.

First, install the @blocknote/xl-docx-exporter and docx packages:

npm install @blocknote/xl-docx-exporter docx

Then, create an instance of the DOCXExporter class. This exposes the following methods:

import {
  DOCXExporter,
  docxDefaultSchemaMappings,
} from "@blocknote/xl-docx-exporter";
import { Packer } from "docx";

// Create the exporter
const exporter = new DOCXExporter(editor.schema, docxDefaultSchemaMappings);

// Convert the blocks to a docxjs document
const docxDocument = await exporter.toDocxJsDocument(editor.document);

// Use docx to write to file:
await Packer.toBuffer(docxDocument);

See the full example below:

Customizing the Docx output file

toDocxJsDocument takes an optional options parameter, which allows you to customize document metadata (like the author) and section options (like headers and footers).

Example usage:

import { Paragraph, TextRun } from "docx";

const doc = await exporter.toDocxJsDocument(testDocument, {
  documentOptions: {
    creator: "John Doe",
  },
  sectionOptions: {
    headers: {
      default: {
        options: {
          children: [new Paragraph({ children: [new TextRun("Header")] })],
        },
      },
    },
    footers: {
      default: {
        options: {
          children: [new Paragraph({ children: [new TextRun("Footer")] })],
        },
      },
    },
  },
});

Custom mappings / custom schemas

The DOCXExporter constructor takes a schema, mappings and options parameter. A mapping defines how to convert a BlockNote schema element (a Block, Inline Content, or Style) to a docxjs element. If you're using a custom schema in your editor, or if you want to overwrite how default BlockNote elements are converted to docx, you can pass your own mappings:

For example, use the following code in case your schema has an extraBlock type:

import {
  DOCXExporter,
  docxDefaultSchemaMappings,
} from "@blocknote/xl-docx-exporter";
import { Paragraph, TextRun } from "docx";

new DOCXExporter(schema, {
  blockMapping: {
    ...docxDefaultSchemaMappings.blockMapping,
    myCustomBlock: (block, exporter) => {
      return new Paragraph({
        children: [
          new TextRun({
            text: "My custom block",
          }),
        ],
      });
    },
  },
  inlineContentMapping: docxDefaultSchemaMappings.inlineContentMapping,
  styleMapping: docxDefaultSchemaMappings.styleMapping,
});

Exporter options

The DOCXExporter constructor takes an optional options parameter. While conversion happens on the client-side, the default setup uses a server hosted proxy to resolve files:

const defaultOptions = {
  // a function to resolve external resources in order to avoid CORS issues
  // by default, this calls a BlockNote hosted server-side proxy to resolve files
  resolveFileUrl: corsProxyResolveFileUrl,
  // the colors to use in the Docx for things like highlighting, background colors and font colors.
  colors: COLORS_DEFAULT, // defaults from @blocknote/core
};