@docx-editor.dev/react

React adapter for the DOCX editor: the packaged root component, provider primitives, shared hooks, and compound chrome, all from the package root.

Install

npm install @docx-editor.dev/react @docx-editor.dev/core

The adapter holds the engine as a peer, so install both; the string catalog comes with it. Add @docx-editor.dev/pro for tracked changes, comments, and custom nodes, or @docx-editor.dev/editor-api to automate the document from code.

Quickstart

import { DocxEditor } from '@docx-editor.dev/react';

export default function App() {
  return <DocxEditor document={docxBytes} />;
}

<DocxEditor> is the full packaged editor: title bar, menu, toolbar, navigation pane, hyperlink popover, context menu, and the painted editable document. On Next.js App Router, render it inside a "use client" component; the editor has nothing to SSR.

Root surface

  • DocxEditor: the one-line host plus compound statics like DocxEditor.Root, DocxEditor.Viewport, DocxEditor.Content, DocxEditor.Toolbar, DocxEditor.Menu, DocxEditor.Navigation, DocxEditor.HyperLink, and DocxEditor.ContextMenu
  • hooks from the same root: useDocxEditor, useEditorState, useEditorCommand, useEditorEvent, usePageSetup, useParagraphIndent, useFontFamily
  • shared top-level pieces: DocxEditorRoot, DocxEditorViewport, DocxEditorContent, DocxEditorToolbar, DocxEditorMenu, DocxEditorNavigation, DocxEditorPageSetupDialog

The review module and sidebar are licensed surfaces in @docx-editor.dev/pro; they are not exports of the React adapter.

There is one export path. Components, hooks, and the engine helpers all live on the package root. There are no /ui, /hooks, or /dialogs subpaths.

Provider primitives

When the packaged chrome is not enough, drop to the same primitives it uses internally:

import { DocxEditor } from '@docx-editor.dev/react';

export function CustomFrame({ bytes }: { bytes: Uint8Array }) {
  return (
    <DocxEditor.Root document={bytes}>
      <DocxEditor.Toolbar />
      <DocxEditor.Viewport>
        <DocxEditor.Navigation />
        <DocxEditor.Content />
        <DocxEditor.HyperLink />
        <DocxEditor.ContextMenu />
      </DocxEditor.Viewport>
    </DocxEditor.Root>
  );
}

Toolbar

The main chrome compound is exported from the package root as DocxEditorToolbar, and attached to the host as DocxEditor.Toolbar:

import { DocxEditor, useEditorCommand } from '@docx-editor.dev/react';

function BoldButton() {
  const bold = useEditorCommand('text.bold');
  return (
    <button
      onMouseDown={(e) => e.preventDefault()} // chrome must not steal the caret
      onClick={() => bold.execute()}
      disabled={!bold.isEnabled}
    >
      Bold
    </button>
  );
}

export function ToolbarOnly({ bytes }: { bytes: Uint8Array }) {
  return (
    <DocxEditor.Root document={bytes}>
      <DocxEditor.Toolbar>
        <BoldButton />
      </DocxEditor.Toolbar>
      <DocxEditor.Viewport>
        <DocxEditor.Content />
      </DocxEditor.Viewport>
    </DocxEditor.Root>
  );
}

The lower-level helpers (useEditorCommand, useEditorState, useFontFamily) also come from the root package.

Editing API

Drive the open document from code with the Office.js-compatible @docx-editor.dev/editor-api/browser, which takes the editor instance this adapter created:

import { useDocxEditor } from '@docx-editor.dev/react';
import { DocxEditor } from '@docx-editor.dev/editor-api/browser';

const editor = useDocxEditor(); // null until the content is mounted
const runtime = DocxEditor.createBrowser(editor!);

The object model and its rules are in Editing API.

Next steps

On this page