@tiptap-pro/extension-export-docx changelog
Changelog for @tiptap-pro/extension-export-docx
0.19.0
Minor Changes
-
Add ordered list numbering format support to DOCX export.
numberingFormats?: NumberingFormatDefinition[]option onExportDocx/exportDocx()/ConvertConfig. Each entry is a multilevel numbering definition (per-level base style, marker template, indent, alignment, font) that the exporter resolves against thenumberingFormatstring attribute on the outermost<ol>of each multilevel list. Unknown / missing ids fall through to the package's default'ordered-list'numbering — consumers who don't opt in see zero behavior change.- New types
NumberingFormatDefinitionandNumberingLevelDefinition. Word's<w:lvlText>grammar (%Nreferences the counter at level N) is used verbatim. No preset formats are shipped — define your own. LevelFormat,IRunOptions, andPositiveUniversalMeasureare re-exported fromdocxso consumers can build definitions without a second import.
Editor-side wiring (the Tiptap attribute extension and the editor-preview CSS) is the consumer's responsibility — a reference implementation is in
demos/src/Extensions/ExportDocxOrderedListNumbering/React/.Also fixes a pre-existing bug where nested ordered lists each allocated their own DOCX
numId, fragmenting counter chains across nesting boundaries. The outermost list's instance id is now threaded through every nestedconvertOrderedListcall so a multilevel list shares onenumIdand Word's per-level counter logic works as expected.
0.18.0
Minor Changes
-
Add
customNodeDsl— a JSON-native way to describe how custom Tiptap nodes should render into DOCX.The existing
customNodesAPI is great inside the editor, but it relies on JavaScript functions, which can't be sent over HTTP. That has historically meant that the DOCX REST API had no way to render application-specific content like callouts, mentions, or hint boxes.customNodeDslcloses that gap with a small, serializable language that produces identical output to the function API and travels cleanly over the wire.What's in the box:
- A versioned wire format (
dslVersion: "1.0") with seven render-node shapes (element,$children,$text,$fragment,$if,$switch,null) and a closed element catalog (Paragraph,TextRun,ExternalHyperlink,Table,TableRow,TableCell,PageBreak). - A typed value-expression layer —
$reffor PM-node attributes,$templatefor string interpolation,$opfor typed compute,$unitfor the same unit helpers the function API ships (pointsToTwips,pixelsToHalfPoints,normalizeColor, …), plus$switch/$iffor conditional rendering. Noeval, no Turing-completeness, no surprises. - Full marks integration —
MarkPolicyon$children/$textandapplyMarkson inline elements, both reusing the same standard mark pipeline as the rest of the converter, plus per-markoverridesanddisablefor fine-grained control. - A clean override-precedence ladder so DSL props compose predictably with
cssStyles,styleOverrides, and the existing*Overridesbundles. - Source-mapped errors (every error carries
dslPathand, at runtime,nodePath+nodeType) and configurable resource caps via the newcustomNodeDslLimitsoption. - Both APIs coexist on the editor — when the same node type appears in both
customNodesandcustomNodeDsl, the function definition wins and a singleconsole.warnis emitted per export. Existing function-based customers see zero behavior change.
Refactoring under the hood: the mark-to-
TextRuntranslation inconvertTextNodewas extracted into reusablecomputeMarkFormattingandbuildTextRunhelpers so the DSL pipeline can drive marks identically without synthesizing fake PM nodes. This is a behavior-preserving change — every existing test passes unchanged.The new
CustomNodeDsl,CustomNodeRule,RenderProgram,RenderNode,ValueExpr,MarkPolicy,ApplyMarksPolicy, andCustomNodeDslLimitstypes are exported from the package root, alongside thecompileCustomNodeDsl,DslCompileError, andDslRuntimeErrorruntime helpers for advanced users running the extension on their own server.TypeScript builder under a tree-shakeable subpath. Authoring rules in TypeScript? Import the fluent builder from
@tiptap-pro/extension-export-docx/dsland let the type system catch containment violations at edit time:import { childrenInline, docxNode, paragraph, ref, template, textRun, } from "@tiptap-pro/extension-export-docx/dsl"; const dsl = { dslVersion: "1.0", nodes: [ docxNode("hintbox") .block() .emit( paragraph({ style: "Hintbox" }).children( childrenInline({ marks: "default" }) ) ) .toJSON(), docxNode("mention") .inline() .emit( textRun({ text: template("@{node.attrs.label}"), color: ref("node.attrs.color", { default: "4472C4", transform: "hexNoHash", }), }).applyMarks("node") ) .toJSON(), ], };What you get:
- Autocomplete on every element prop.
paragraph({ … })suggestsstyle,alignment,spacing,border,shading, … exactly the field set the DSL compiler validates. - Compile-time containment safety.
paragraph().children(childrenBlock())is a TypeScript error — paragraphs only accept inline children.table().rows(paragraph())is also an error —Table.rowsrequiresTableRowbuilders. The errors fire at edit time, not at runtime. - Required-prop checking.
externalHyperlink({})is a TypeScript error: thelinkprop is required. - Wire-format compatibility.
.toJSON()produces the exact same JSON the Custom-nodes DSL compiler accepts. Same payload works inside the editor, in a Node.js server, or as acustomNodeDslfield over the convert REST API. - Tree-shakeable. The builder ships under a separate
./dslsubpath in the package'sexportsfield — callers who never touch it don't pay for it.
The full builder surface (
docxNode,paragraph,textRun,externalHyperlink,table,tableRow,tableCell,pageBreak,childrenInline/childrenBlock/childrenTableRow/childrenTableCell,iff/switch_/fragment/textOp,ref/template/op/unit/switchValue/marks, plus all per-element prop interfaces) is documented at Custom-nodes DSL builder.Inline decoration on
Paragraph. The DSLParagraphelement gainsborderandshadingprops that mirror theIParagraphOptionsshape on docx.js. Custom nodes that previously needed a namedstyleOverrides.paragraphStylesentry purely to carry decorative chrome (boxes, callouts, hint boxes) can now express it inline on the DSL element — no parallel style declaration, no round-trip indirection. The named-style label still works for round-trip identity (<w:pStyle>survives whether or not it's declared instyles.xml), so existing payloads keep behaving the same.See the new Custom-nodes DSL docs for the JSON spec, worked examples (hintbox, mention, callout box, code block, custom link), and the precedence model — and the DSL builder docs for the TypeScript-ergonomic equivalent.
- A versioned wire format (
-
Add a
pageColoroption toExportDocxandconvert()that writes the DOCXw:backgroundelement, letting Word display the document with a colored page. Accepts any CSS color the package'snormalizeColorhelper resolves (hex,rgb()/rgba(), named colors);"transparent"and unresolvable values omit the element. Note that Word does not print page background by default — users must enable "Print background colors and images" under Word Options for the color to appear in printed output or PDF exports. -
Configurable header/footer placeholders with end-to-end DOCX round-trip support.
- Pages: new
placeholdersoption to rename the built-in{page}/{total}tokens or disable substitution. Defaults preserve existing behavior. - ExportDocx: header/footer text now translates registered tokens into live Word
PAGE/NUMPAGESfields instead of literal text. When the Pages extension is installed, the export auto-picks up itsplaceholdersconfig so the editor preview and the exported.docxstay aligned. Body content is never substituted. - ImportDocx: the importer now forwards
Pages.options.placeholdersto the convert service so WordPAGE/NUMPAGESfields come back as text tokens that match your active Pages registry —{page}/{total}by default, or your rename. The editor preview substitutes the imported tokens natively, with no.replace()step and noplaceholders: { total: 'numpages' }workaround. Passplaceholders: falseon the command to opt out, orplaceholders: { page, total }to override the editor's registry per-call.
The convert service exposes the same
placeholdersfield on/import/docxand/export/docxfor direct REST API callers who want the same control without an editor. - Pages: new
0.17.0
Minor Changes
- Add export docx missing overrides for header and footers
- DOCX export now serializes
subscriptandsuperscripttext marks. Content like H₂O and x² preserves its formatting on export, where it was previously emitted as plain text.
Patch Changes
- Update fast-xml-parser to patch vulnerabilities CVE-2026-33349 and CVE-2026-41650
0.16.1
Patch Changes
- Fix image dimensions in DOCX export. Images were previously shrunk to 75 % of their intended size because pixel values were converted to points before being passed to
docx'sImageRun.transformation, which already expects pixels at 96 dpi.
0.16.0
Minor Changes
-
Add support for paragraph, table, text run, table cell, and image overrides in header and footer content. Also add a new
headerFooterOverridesoption for styling headers and footers separately from the body.convertHeaderandconvertFooternow accept these options:customNodes,pageSize,pageMargins,tableOverrides,tableCellOverrides,paragraphOverrides,textRunOverrides,imageOverrides. Before, header and footer content was always converted with default values, so the overrides did not work.- New option
headerFooterOverridesinExportDocxOptions. You can use this to style header and footer content different from the body. Each field replaces the body-wide value, it does not merge. If a field is not set, it uses the body value. This only works for headers and footers that come from the Pages extension. - Fix: when you set
paragraphOverrides.spacing.beforeorspacing.after, the values were lost because the code overwrote the spacing object with onlyspacing.line. Nowbefore,after, andlineall work together.
-
Add
headerandfooterproperties to thepageMarginsoption, controlling the distance from the page edge to the header/footer. When the Pages extension is configured, these values are auto-derived fromheaderTopMarginandfooterBottomMargin; caller-provided values always take precedence.For
extension-export-pdf,extension-export-doc, andextension-export-odt, full end-to-end support requires the Tiptap convert service to be on a version that accepts the newpageMargins.header/footerfields and ships an updated@tiptap-pro/extension-export-docx.
0.15.5
Patch Changes
- Render
{page}and{total}tokens in plain-text headers and footers as livePageNumber.CURRENT/PageNumber.TOTAL_PAGESfields, so exported DOCX files show the actual page number and total page count instead of the literal token strings.
0.15.4
Patch Changes
- Inline images inside a paragraph now inherit the paragraph's formatting (alignment, line spacing,
paragraphOverrides, heading level, list numbering) in the DOCX export. Previously these attributes were dropped because the image was emitted as its own wrapper paragraph. Block-level images (siblings of paragraphs) and the publicconvertImageAPI are unchanged; a newconvertImageRunhelper is exported for callers that need the raw inline run.
0.15.3
Patch Changes
- Fix DOCX rendering in viewers that don't support universal measures by converting page dimensions and margins to numeric twips, and add explicit document defaults for font size, font family, and language settings
0.15.2
Patch Changes
- Minor bugfixes & improvements
0.15.1
Patch Changes
- fix: do not overwrite global default styles
0.15.0
Minor Changes
- Add page break support to DOCX export. The
pageBreaknode is now converted to a<w:br w:type="page"/>element, producing a standard Word page break in the exported document. A newconvertPageBreakfunction is also publicly exported for use in custom node conversion pipelines.
0.14.0
Minor Changes
- Fix table cells only rendering paragraphs by delegating to the central node converter, enabling support for lists, headings, images, blockquotes, and nested tables inside table cells
0.13.0
Minor Changes
-
Extend DOCX export with deep customization overrides for paragraphs, text runs, table cells, and images.
tableOverrides(new)Allows overriding any
ITableOptionsproperty exceptrows. Values are spread last, so user-provided table-level properties (borders, margins, layout) win over computed defaults.paragraphOverrides(new)Accepts any
IParagraphOptionsproperty exceptchildren. Spread first as base defaults — per-node computed values like alignment, spacing, heading level, and list numbering override them. Applied to all paragraph creation paths: standard paragraphs, headings, blockquotes, bullet lists, ordered lists, and list items.textRunOverrides(new)Accepts any
IRunOptionsproperty excepttext. Spread first as base defaults — per-mark formatting (bold, italic, underline, font family, font size, color, highlight, etc.) overrides them. Useful for setting a default font or size across the entire exported document. Applied to all text run creation paths including styled paragraphs (e.g. blockquotes) and standard content.tableCellOverrides(new)Accepts any
ITableCellOptionsproperty exceptchildren. Spread first as base defaults — per-cell computed values like width, column span, and width type override them. Useful for applying consistent cell shading, vertical alignment, or border styles across all table cells.imageOverrides(new)Accepts any
IImageOptionsproperty exceptdata,type, andfallback. Spread last so user-provided values (e.g. customtransformationdimensions) win over the intrinsic dimensions detected from the image buffer. SVG fallback data is always preserved regardless of overrides.Usage example
editor.commands.exportDocx({ onCompleteExport: (result) => { /* ... */ }, exportType: "blob", paragraphOverrides: { spacing: { after: 200, before: 100 }, }, textRunOverrides: { font: "Arial", size: 24, // 12pt in half-points }, tableCellOverrides: { shading: { fill: "F0F0F0", type: ShadingType.SOLID }, }, imageOverrides: { transformation: { width: 400, height: 300 }, }, });Note: All override objects use shallow spreading, not deep merging. When overriding nested properties like
spacingortransformation, provide the complete nested object to avoid undefined fields.
Node attribute inference (new)
The DOCX export now respects node-level attributes set by the editor instead of always computing values from scratch.
Image
width/heightfrom node attrsWhen an image has been resized in the editor (via
ResizableNodeView), the user-setwidthandheightattributes are now used for the exported dimensions instead of the intrinsic image dimensions. If only one dimension is set, the other is computed proportionally from the intrinsic aspect ratio. Priority chain:imageOverrides.transformation>node.attrs.width/height> intrinsic dimensions.Image
alttextThe
altattribute on image nodes is now mapped to the docxaltTextproperty (DocPropertiesOptions.name), providing accessibility metadata in the exported document.Table cell
colwidthWhen table columns have been resized in the editor, the per-cell
colwidthattribute (pixel array) is now used to compute precise column widths in the export. Falls back to even distribution whencolwidthis not set.Table cell
rowspanThe
rowspanattribute on table cells is now supported. Cells spanning multiple rows are correctly exported with therowSpanproperty in the docx output.Paragraph
textAlign: 'justify'Justified text alignment is now correctly mapped to
AlignmentType.JUSTIFIEDin the export. Previously,'justify'fell through to left alignment.Text run
backgroundColorThe
backgroundColorattribute on thetextStylemark is now exported as solid character shading on text runs. Previously, inline background colors were silently dropped. -
Initial beta point for export and pages packages
3.0.0-beta.31
3.0.0-beta.30
Patch Changes
- Bumped Tiptap and Hocuspocus Dependencies to most recent version
3.0.0-beta.29
3.0.0-beta.28
3.0.0-beta.27
3.0.0-beta.26
3.0.0-beta.25
Patch Changes
- Bumped @tiptap and @hocuspocus dependencies
3.0.0-beta.24
Patch Changes
- Bump tiptap and hocuspocus dependencies
3.0.0-beta.23
3.0.0-beta.22
Patch Changes
- upgraded hocuspocus and tiptap dependencies
3.0.0-beta.21
3.0.0-beta.20
Patch Changes
- Bumped tiptap and hocuspocus dependencies
3.0.0-beta.19
3.0.0-beta.18
Patch Changes
- updated tiptap and hocuspocus dependencies
3.0.0-beta.17
3.0.0-beta.16
Patch Changes
- Updated tiptap packages
3.0.0-beta.15
Major Changes
- Updated all tiptap dependencies
0.1.0
Initial release of extension-export-docx as beta version.