React

Props

A curated reference for DocxEditorProps, grouped by concern, with examples for the most common configuration patterns of the React component.

<DocxEditor> is configured through props. Groups below match how you'd reach for them in practice. The full generated reference (every prop, every type signature) is at /docs/1.x/api/react.

Document input

How the editor receives the document. Use documentBuffer for raw bytes; use document when you've already parsed.

PropTypeDescription
documentBufferDocxInput | nullArrayBuffer, Uint8Array, Blob, or File. Most common entry. null mounts an empty document.
documentDocument | nullPre-parsed -core document tree. Skip the parser if you already have one.
// From a fetch
const buf = await fetch('/template.docx').then((r) => r.arrayBuffer());
<DocxEditor documentBuffer={buf} />;

// From a file input (File is accepted directly, no arrayBuffer() needed)
<input type="file" accept=".docx" onChange={(e) => setFile(e.target.files?.[0] ?? null)} />
<DocxEditor documentBuffer={file} />

// Empty document (mounts with no content; useful when collecting input from scratch)
<DocxEditor documentBuffer={null} />

Mode and read-only

Editing mode and the suggest/view/read-only states. Pair with onModeChange for controlled mode.

PropTypeDefaultDescription
modeEditorMode'editing''editing' | 'suggesting' | 'viewing'. For read-only, use the readOnly boolean below.
onModeChange(mode) => voidControlled mode handler. Without it, the editor manages mode internally.
readOnlybooleanfalseIndependent of mode. Disables every input affordance (typing, toolbar buttons, dialogs) regardless of which mode is active.
const [mode, setMode] = useState<EditorMode>('editing');

<DocxEditor
  documentBuffer={buf}
  mode={mode}
  onModeChange={setMode}
/>;

'suggesting' wraps every edit as a tracked change. Use it for review flows.

Comments and collaboration

Pull author identity in, push comment state back out.

PropTypeDescription
authorstringAuthor name attached to new comments and tracked changes.
commentsComment[]Controlled comments. Pair with onCommentsChange.
onCommentsChange(comments) => voidFires on any comment mutation. Mirror into Y.Array for live sync.
onCommentAdd / onCommentResolve / onCommentDelete / onCommentReplycallbacksGranular events when you want to log or trigger side effects, not own state.
const [comments, setComments] = useState<Comment[]>([]);

<DocxEditor
  documentBuffer={buf}
  author='Jess Lin'
  comments={comments}
  onCommentsChange={setComments}
/>;

Controlled comments (comments + onCommentsChange) are React-only today; the Vue adapter exposes the callback events but not the comments prop (see Vue props).

For Yjs-backed sync, see Realtime collaboration.

Toolbar UI

Toggle the built-in UI on or off.

PropTypeDefaultDescription
showToolbarbooleantrueToolbar visibility. Pass false and compose your own from /ui.
showZoomControlbooleantrueBottom-right zoom widget.
showRulerbooleanfalsePage ruler above the document body.
rulerUnit'inch' | 'cm''inch'Ruler unit.
showMarginGuidesbooleanfalseFaint guides at page margins.
marginGuideColorstring'#c0c0c0'CSS color for the guides above.
showOutlinebooleanfalseDocument outline / table of contents drawer.
showOutlineButtonbooleantrueOutline toggle button in the toolbar.
showFileOpenbooleantrueShow File > Open and enable Cmd/Ctrl+O. Set false when your app provides its own open action.
showHelpMenubooleantrueShow the Help menu in the menu bar. Set false to hide it.
initialZoomnumber1.0Starting zoom (1.0 = 100%).

The font picker and custom font registration have their own section below.

// Editor without built-in toolbar UI.
<DocxEditor documentBuffer={buf} showToolbar={false} showZoomControl={false} />

Appearance (dark mode)

PropTypeDefaultDescription
colorMode'light' | 'dark' | 'system''light'Editor theme. 'system' follows the OS prefers-color-scheme.

Dark mode is controlled entirely by this prop; there is no internal toggle. Drive it from your own UI by flipping the value:

const [colorMode, setColorMode] = useState<'light' | 'dark'>('light');

<button onClick={() => setColorMode((m) => (m === 'dark' ? 'light' : 'dark'))}>
  Toggle theme
</button>
<DocxEditor documentBuffer={buf} colorMode={colorMode} />

See the Dark mode guide for how the canvas transform works, what it does and doesn't change, and how to report issues.

Fonts

fontFamilies controls what the toolbar dropdown offers. fonts (added in 1.1.0) registers the actual font faces so the editor can render and measure them. They are independent: list a family in fontFamilies to make it pickable, register it with fonts so its glyphs paint correctly.

PropTypeDefaultDescription
fontsReadonlyArray<FontDefinition>noneCustom font faces to register before the editor measures text. Each entry injects one @font-face.
fontFamiliesReadonlyArray<string | FontOption>built-in 12Constrain the font picker to a specific list.
onFontsLoaded() => voidnoneFires once the registered faces are ready.

A FontDefinition is { family, src, weight? }. src is a URL to a woff2/woff/ttf/otf file you host. Register multiple weights of the same family as separate entries that share family:

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

const FONTS = [
  { family: 'Custom Sans', src: '/fonts/CustomSans-Regular.woff2' },
  { family: 'Custom Sans', src: '/fonts/CustomSans-Bold.woff2', weight: 700 },
];

<DocxEditor
  documentBuffer={buf}
  fonts={FONTS}
  fontFamilies={['Custom Sans', 'Arial', 'Times New Roman']}
/>;

Pass a stable reference (module-level or memoized). Inline arrays re-register on every render; the loader dedupes by family|weight|style so it's harmless, but it wastes work.

Font-load failures route through onError (see Callbacks), so you can forward them to your own tracker. With no onError attached they fall back to console.warn.

For host code that isn't using the React or Vue adapter, @eigenpal/docx-editor-core/utils exports loadFontFromUrl, loadFontDefinitions, onFontError, and the FontDefinition type so you can drive the same registration directly.

Title bar customization

The header strip is fully overridable.

PropTypeDescription
documentNamestringDisplay name in the title bar.
onDocumentNameChange(name) => voidFires when the user edits the title in-place.
documentNameEditablebooleanDefault true. Set false to lock the title.
renderLogo() => ReactNodeLeft-side logo slot. Default renders the document icon.
renderTitleBarRight() => ReactNodeRight-side slot. Wire your save status, share button, avatars.
toolbarExtraReactNodeExtra items appended to the toolbar.
<DocxEditor
  documentBuffer={buf}
  documentName={file.name}
  onDocumentNameChange={(name) => updateMetadata({ name })}
  renderTitleBarRight={() => <SaveIndicator dirty={dirty} />}
/>;

The Vue adapter exposes the same areas as named slots (#title-bar-left, #title-bar-right, #toolbar-extra); see Vue props.

Callbacks

Lifecycle and integration hooks.

PropTypeDescription
onChange(doc: Document) => voidFires on every document mutation. Throttle for autosave.
onSave(buf: ArrayBuffer) => voidFires when the user invokes Save (Cmd+S or toolbar).
onOpen(file: File) => void | Promise<void>Replaces the built-in post-pick load for File > Open and Cmd/Ctrl+O. The native picker still opens; your callback receives the selected file.
onSelectionChange(state: SelectionState | null) => voidSelection metadata for custom UI (active marks, paragraph style, etc.).
onError(error: Error) => voidErrors during parse or render. Send to your error tracker.
onFontsLoaded() => voidFired once the font set is ready. Use to defer measurement-sensitive UI.
onPrint / onCopy / onCut / onPaste() => voidNotification hooks for clipboard and print events.
<DocxEditor
  documentBuffer={buf}
  onChange={(doc) => debouncedAutosave(doc)}
  onSave={async (buf) => {
    await fetch('/api/documents/1', { method: 'PUT', body: buf });
  }}
  onOpen={async (file) => {
    await importDocument(file);
  }}
  onError={(err) => reportError(err)}
/>;

onOpen is useful when externalContent or collaborative bindings own the document state. Omit it to keep the built-in local load behavior. Pair it with showFileOpen={false} when you want to remove the built-in menu item and wire your own button.

Styling

PropTypeDescription
themeTheme | nullOOXML document theme (colorScheme, fontScheme) used to resolve theme colors and theme fonts. Normally parsed from the file; pass one to override. Not UI styling tokens.
classNamestringApplied to the editor root element.
styleCSSPropertiesInline styles on the root.
placeholderReactNodeRendered while there's no document content.
loadingIndicatorReactNodeRendered while the buffer is being parsed.
printOptionsPrintOptionsMargins, header/footer toggles for the print pipeline.
<DocxEditor
  documentBuffer={buf}
  className='rounded-lg shadow-md'
  loadingIndicator={<Spinner label='Loading document' />}
  placeholder={<EmptyState />}
/>;

i18n

PropTypeDescription
i18nLocaleStrings | PartialLocaleStringsLocale data from @eigenpal/docx-editor-i18n. See i18n page.
import pl from '@eigenpal/docx-editor-i18n/pl';

<DocxEditor documentBuffer={buf} i18n={pl} />;

Agents

PropTypeDescription
agentPanelAgentPanelOptionsWires a side panel slot. Pair with useDocxAgentTools.
<DocxEditor
  ref={editorRef}
  documentBuffer={buf}
  agentPanel={{ render: () => <AgentChatLog messages={messages} /> }}
/>;

agentPanel is React-only; the Vue adapter pairs useAgentBridge with your own chat UI instead. Full setup in Agents → Live editor.

Plugins

PropTypeDescription
externalPluginsPlugin[]ProseMirror plugins appended to the editor's plugin list.
pluginOverlaysReactNodeAbsolutely-positioned overlay slot for plugin UI.
pluginSidebarItemsReactSidebarItem[]Sidebar entries contributed by plugins.
pluginRenderedDomContextRenderedDomContext | nullHand-off when you need plugin code to read editor DOM measurements.

See Plugins for the full plugin contract.

Ref methods

Imperative API exposed through forwardRef. Capture a DocxEditorRef and call methods directly when you need to drive the editor from outside React state.

import { useRef } from 'react';
import { DocxEditor, type DocxEditorRef } from '@eigenpal/docx-editor-react';

const editorRef = useRef<DocxEditorRef>(null);

editorRef.current?.addComment({
  paraId: 'ABC12300',
  text: 'Tighten this paragraph.',
  author: 'Jess Lin',
});
editorRef.current?.scrollToParaId('DEF45600');
// Scroll and briefly flash the paragraph so the user can spot it:
editorRef.current?.scrollToParaId('DEF45600', {
  highlight: { color: 'rgba(255, 235, 59, 0.55)', durationMs: 1200 },
});
const buf = await editorRef.current?.save(); // Promise<ArrayBuffer | null>

Common methods:

MethodReturnsWhat it does
save()Promise<ArrayBuffer | null>Serialize the current document to a .docx buffer. null if there is no document.
addComment({ paraId, text, author })number | nullAdd a comment anchored to a paragraph by w14:paraId. Returns the new comment id, or null if the paragraph wasn't found.
proposeChange({ paraId, search, replaceWith, author })booleanInsert a tracked change. false if the search text wasn't found.
findInDocument(query, options?)Array<{ paraId, match, before, after }>Search the document; each hit carries its paragraph id and surrounding context.
scrollToParaId(paraId, options?)booleanScroll to a paragraph by w14:paraId. Returns false if not found. Pass { highlight: { color?, durationMs? } } to briefly flash the paragraph after scrolling.
scrollToPosition(pos)voidScroll to a raw ProseMirror position.
getDocument()Document | nullSnapshot of the parsed tree. null before a document is loaded.

The full method list with signatures is at /docs/1.x/api/react.

Next steps

On this page