Pages extension API reference
This page is the canonical reference for the Pages extension's options, commands, and storage. For task-focused walkthroughs, see Page format, Page header and footer, Page gap, Page break node, and Zoom.
Options interface
import type { Extensions, JSONContent } from '@tiptap/core'
type PagesHeaderFooter = string | JSONContent
type BuiltInPageFormat = 'A4' | 'A3' | 'A5' | 'Letter' | 'Legal' | 'Tabloid'
interface CustomPageFormat {
id: string
width: number // pixels
height: number // pixels
margins: {
top: number
right: number
bottom: number
left: number
}
}
type PageFormat = BuiltInPageFormat | CustomPageFormat
interface PagesOptions {
/** Built-in format name or custom page format object. Default: 'A4'. */
pageFormat: PageFormat
/** Initial zoom level. Clamped to [0.25, 4]. Default: 1. */
zoom?: number
/** Default header content. Accepts a plain string, an HTML string, or Tiptap JSONContent.
* Supports `{page}` and `{total}` placeholders. Default: ''. */
header: string | JSONContent
/** Default footer content. Same shape as `header`. Default: ''. */
footer: string | JSONContent
/** Distance from the page top to where the header content starts (pixels).
* Defaults to 50% of the page top margin. */
headerTopMargin?: number
/** Distance from the footer content bottom to the page bottom (pixels).
* Defaults to 50% of the page bottom margin. */
footerBottomMargin?: number
/** Visual gap between pages (pixels). Default: 50. */
pageGap?: number
/** CSS color shown in the area between pages. Default: '#ffffff'. */
pageGapBackground?: string
/** Accent color applied to both header and footer editor overlays. Default: '#6366f1'. */
accentColor?: string
/** Accent color for the header overlay only. Defaults to the `accentColor` value. */
headerAccentColor?: string
/** Accent color for the footer overlay only. Defaults to the `accentColor` value. */
footerAccentColor?: string
/** Enable a different header and footer for the first page (Word's "Different First Page").
* Default: false. */
differentFirstPage?: boolean
/** First-page header content. Default: ''. */
headerFirstPage?: PagesHeaderFooter
/** First-page footer content. Default: ''. */
footerFirstPage?: PagesHeaderFooter
/** Enable different headers and footers on odd vs. even pages (Word's "Different Odd & Even Pages").
* Default: false. */
differentOddEven?: boolean
/** Odd-pages header content. Default: ''. */
headerOdd?: PagesHeaderFooter
/** Even-pages header content. Default: ''. */
headerEven?: PagesHeaderFooter
/** Odd-pages footer content. Default: ''. */
footerOdd?: PagesHeaderFooter
/** Even-pages footer content. Default: ''. */
footerEven?: PagesHeaderFooter
/** Whether double-clicking the header opens the inline editor overlay.
* When false, the overlay cannot be opened by users or by `openHeaderEditor`.
* Default: true. */
editableHeader?: boolean
/** Whether double-clicking the footer opens the inline editor overlay.
* When false, the overlay cannot be opened by users or by `openFooterEditor`.
* Default: true. */
editableFooter?: boolean
/** Enable a different first-page footer independently of `differentFirstPage`.
* Set automatically when `setDifferentFirstPage(true)` is called. */
differentFirstPageFooter?: boolean
/** Enable different odd/even footers independently of `differentOddEven`.
* Set automatically when `setDifferentOddEven(true)` is called. */
differentOddEvenFooter?: boolean
/** Extensions registered on the inner header/footer editors.
* Defaults to StarterKit; mirror your main editor's stack to keep schemas aligned. */
headerFooterExtensions?: Extensions
/** Called when `setPageFormat()` succeeds, or when configure() applies a new format. */
onPageFormatChange?: (pageFormat: PageFormat) => void
/** Called when `setZoom()` changes the zoom level. */
onZoomChange?: (zoom: number) => void
/** Optional — return true to keep the active header or footer editor open when the user
* double-clicks outside it. Applies to both. */
onDblClickHeaderFooterPreventClose?: (event: MouseEvent) => boolean
/** Like `onDblClickHeaderFooterPreventClose`, but only for the header overlay.
* Takes priority over the fallback when both are set. */
onDblClickHeaderPreventClose?: (event: MouseEvent) => boolean
/** Like `onDblClickHeaderFooterPreventClose`, but only for the footer overlay.
* Takes priority over the fallback when both are set. */
onDblClickFooterPreventClose?: (event: MouseEvent) => boolean
/** Rename the built-in `{page}` / `{total}` placeholder tokens, or pass
* `false` to disable substitution entirely. Default: undefined (use built-ins as-is). */
placeholders?: false | { page?: string; total?: string }
}Options reference
Layout
| Option | Type | Default | Notes |
|---|---|---|---|
pageFormat | PageFormat | 'A4' | See Page format for built-ins. |
zoom | number | 1 | Clamped to [0.25, 4]. See Zoom. |
pageGap | number | 50 | Pixels. Visual only — does not affect export. |
pageGapBackground | string | '#ffffff' | Any CSS color value. |
Headers and footers
The full reference for header/footer options lives on Page header and footer. The table below summarises the surface; for first-page, odd/even, content types, and editor-overlay behaviour, follow the link.
| Option | Type | Default | Description |
|---|---|---|---|
header | PagesHeaderFooter | '' | Default header content |
footer | PagesHeaderFooter | '' | Default footer content |
headerTopMargin | number | 50% of top margin | Distance from page top to header content (px) |
footerBottomMargin | number | 50% of bottom margin | Distance from footer content to page bottom (px) |
differentFirstPage | boolean | false | First-page header and footer differ from the rest |
headerFirstPage | PagesHeaderFooter | '' | First-page header content |
footerFirstPage | PagesHeaderFooter | '' | First-page footer content |
differentOddEven | boolean | false | Odd/even pages have different headers and footers |
headerOdd | PagesHeaderFooter | '' | Odd-pages header content |
headerEven | PagesHeaderFooter | '' | Even-pages header content |
footerOdd | PagesHeaderFooter | '' | Odd-pages footer content |
footerEven | PagesHeaderFooter | '' | Even-pages footer content |
editableHeader | boolean | true | Allow opening the header overlay on double-click |
editableFooter | boolean | true | Allow opening the footer overlay on double-click |
headerFooterExtensions | Extensions | StarterKit | Extensions for the inner header/footer editors |
onDblClickHeaderFooterPreventClose | (event: MouseEvent) => boolean | undefined | Prevent closing on double-click outside (header + footer) |
onDblClickHeaderPreventClose | (event: MouseEvent) => boolean | undefined | Prevent closing on double-click outside (header only) |
onDblClickFooterPreventClose | (event: MouseEvent) => boolean | undefined | Prevent closing on double-click outside (footer only) |
accentColor | string | '#6366f1' | Accent color for both overlays |
headerAccentColor | string | accentColor value | Accent color for the header overlay only |
footerAccentColor | string | accentColor value | Accent color for the footer overlay only |
placeholders | false | { page?, total? } | undefined | Rename {page} / {total} tokens, or false to disable |
Callbacks
| Option | Type | Description |
|---|---|---|
onPageFormatChange | (format: PageFormat) => void | Fired when the page format changes via configure or setPageFormat. |
onZoomChange | (zoom: number) => void | Fired when the zoom level changes via setZoom. |
Commands reference
For deep treatment of each command, see the linked core-concepts page.
Layout commands
| Command | Parameters | Description |
|---|---|---|
setPageFormat | pageFormat: PageFormat | Change the page format. Fires onPageFormatChange. |
setZoom | zoom: number | Set zoom (clamped to [0.25, 4]). Fires onZoomChange. |
setPageGap | pageGap: number | Set the gap between pages (px). Must be positive. |
setPageGapBackground | color: string | Set the page-gap background color (any CSS color value). |
Header / footer commands
The full reference also lives on Page header and footer.
| Command | Parameters | Description |
|---|---|---|
setHeader | header: PagesHeaderFooter | Set the default header content |
setFooter | footer: PagesHeaderFooter | Set the default footer content |
setHeaderTopMargin | margin: number | Set header top margin (px) |
setFooterBottomMargin | margin: number | Set footer bottom margin (px) |
setDifferentFirstPage | enabled: boolean | Toggle different first-page header and footer |
setDifferentFirstPageFooter | enabled: boolean | Toggle different first-page footer independently |
setHeaderFirstPage | header: PagesHeaderFooter | Set first-page header content |
setFooterFirstPage | footer: PagesHeaderFooter | Set first-page footer content |
setDifferentOddEven | enabled: boolean | Toggle different odd/even headers and footers |
setDifferentOddEvenFooter | enabled: boolean | Toggle different odd/even footers independently |
setHeaderOdd | header: PagesHeaderFooter | Set odd-pages header content |
setHeaderEven | header: PagesHeaderFooter | Set even-pages header content |
setFooterOdd | footer: PagesHeaderFooter | Set odd-pages footer content |
setFooterEven | footer: PagesHeaderFooter | Set even-pages footer content |
setHeaderEditable | enabled: boolean | Lock or unlock the header overlay (controls editableHeader). |
setFooterEditable | enabled: boolean | Lock or unlock the footer overlay (controls editableFooter). |
openHeaderEditor | { pageNumber: number } | Open header editor for a specific page (1-indexed). |
openFooterEditor | { pageNumber: number } | Open footer editor for a specific page (1-indexed). |
closeHeaderFooterEditors | none | Close whichever header/footer editor is open |
closeHeaderEditor | none | Close the header editor if open |
closeFooterEditor | none | Close the footer editor if open |
setAccentColor | color: string | Set accent color for both editor overlays |
setHeaderAccentColor | color: string | Set accent color for the header overlay only |
setFooterAccentColor | color: string | Set accent color for the footer overlay only |
Storage reference
Read these from editor.storage.pages. Properties marked read-only should not be written directly — use the matching command.
Layout
| Property | Type | Description |
|---|---|---|
pageFormat | PageFormat | Current page format |
zoom | number | Current zoom level (read-only — use setZoom) |
getZoom | () => number | Convenience getter for the current zoom |
pageGap | number | Current gap between pages (px) |
pageGapBackground | string | Current page-gap background color |
getCurrentPage | () => number | null | The 1-indexed page number where the cursor sits |
getDistanceToNextPagebreak | (pos: number) => number | null | Pixel distance from pos to the next page break |
getDistanceToPrevPagebreak | (pos: number) => number | null | Pixel distance from pos to the previous page break |
Headers and footers (rendered HTML and JSON)
After a user edits a header or footer through its overlay, both the rendered HTML and the underlying Tiptap JSON are exposed on storage. Use the JSON forms when serialising for DOCX export. The HTML properties are always strings (defaulting to '' before any edit). The JSON properties are null until the user first edits the corresponding header or footer through its overlay.
| Property | Type | Description |
|---|---|---|
headerHTML | string | Default header rendered HTML |
headerJSON | Record<string, any> | null | Default header as Tiptap JSON |
headerFirstPageHTML | string | First-page header rendered HTML |
headerFirstPageJSON | Record<string, any> | null | First-page header as Tiptap JSON |
headerOddHTML | string | Odd-pages header rendered HTML |
headerOddJSON | Record<string, any> | null | Odd-pages header as Tiptap JSON |
headerEvenHTML | string | Even-pages header rendered HTML |
headerEvenJSON | Record<string, any> | null | Even-pages header as Tiptap JSON |
footerHTML | string | Default footer rendered HTML |
footerJSON | Record<string, any> | null | Default footer as Tiptap JSON |
footerFirstPageHTML | string | First-page footer rendered HTML |
footerFirstPageJSON | Record<string, any> | null | First-page footer as Tiptap JSON |
footerOddHTML | string | Odd-pages footer rendered HTML |
footerOddJSON | Record<string, any> | null | Odd-pages footer as Tiptap JSON |
footerEvenHTML | string | Even-pages footer rendered HTML |
footerEvenJSON | Record<string, any> | null | Even-pages footer as Tiptap JSON |
differentFirstPage | boolean | Whether the first page differs |
differentOddEven | boolean | Whether odd/even pages differ |
differentFirstPageFooter | boolean | First-page footer differs (independent flag) |
differentOddEvenFooter | boolean | Odd/even footers differ (independent flag) |
editableHeader | boolean | Whether the header overlay can be opened (read-only — use setHeaderEditable) |
editableFooter | boolean | Whether the footer overlay can be opened (read-only — use setFooterEditable) |
accentColor | string | Current accent color (both) |
headerAccentColor | string | Current header accent color |
footerAccentColor | string | Current footer accent color |
Active inner-editor state
When a header or footer overlay is open, these properties reflect which one is active. Useful for building toolbars that follow the focused editor — see Page header and footer for a complete toolbar example.
| Property | Type | Description |
|---|---|---|
activeEditor | Editor | null | The active header/footer editor instance, or null |
activeEditorType | 'header' | 'footer' | null | Which kind of overlay is active |
activePageNumber | number | null | Page number being edited |
headerEditorOn | Editor['on'] | null | Pre-bound subscriber for events on the header overlay's inner editor |
headerEditorOff | Editor['off'] | null | Pre-bound unsubscriber for the header overlay's inner editor |
footerEditorOn | Editor['on'] | null | Pre-bound subscriber for events on the footer overlay's inner editor |
footerEditorOff | Editor['off'] | null | Pre-bound unsubscriber for the footer overlay's inner editor |
Example usage
Built-in format
import { Editor } from '@tiptap/core'
import { ConvertKit } from '@tiptap-pro/extension-convert-kit'
import { TableKit } from '@tiptap-pro/extension-pages-tablekit'
import { Pages } from '@tiptap-pro/extension-pages'
const editor = new Editor({
extensions: [
ConvertKit.configure({ table: false }),
TableKit,
Pages.configure({
pageFormat: 'A4',
pageGap: 40,
header: 'My Project',
footer: 'Page {page} of {total}',
pageGapBackground: '#f8f8f8',
}),
],
})Custom format and a runtime change
import { cmToPixels } from '@tiptap-pro/extension-pages'
Pages.configure({
pageFormat: {
id: 'custom-page-format',
width: cmToPixels(22.94),
height: cmToPixels(35.18),
margins: {
top: cmToPixels(2.54),
right: cmToPixels(2.54),
bottom: cmToPixels(2.54),
left: cmToPixels(2.54),
},
},
onPageFormatChange: (pageFormat) => {
console.log('Page format changed:', pageFormat.id)
},
})
// Switch later
editor.commands.setPageFormat('Letter')Header and footer template tokens
Both header and footer accept the tokens {page} (current 1-indexed page) and
{total} (total page count). They are substituted at render time and work in plain
strings, HTML strings, and JSONContent.