Pages extension API reference
interface PagesOptions {
/**
* Page format that determines page size and margins.
* Can be a built-in format name or a custom page format object.
* Built-in formats: A4, A3, A5, Letter, Legal, Tabloid
* @default 'A4'
*/
pageFormat: 'A4' | 'A3' | 'A5' | 'Letter' | 'Legal' | 'Tabloid' | PageFormat
/**
* Height of the page header in pixels.
* @default 50
*/
headerHeight?: number
/**
* Height of the page footer in pixels.
* @default 50
*/
footerHeight?: number
/**
* Gap between pages in pixels.
* @default 50
*/
pageGap?: number
/**
* Header content for every page. Can be a string (with tokens) or a function.
* @default ''
*/
header?: string | ((page: number, total: number) => string)
/**
* Footer content for every page. Can be a string (with tokens) or a function.
* @default '
*/
footer?: string | ((page: number, total: number) => string)
/**
* Background color for the page gap area.
* @default undefined
*/
pageGapBackground?: string
/**
* Callback function called when the page format changes.
* Receives the new page format as an argument.
* @default () => {}
*/
onPageFormatChange?: (pageFormat: PageFormat) => void
/**
* Initial zoom level for visual scaling. Clamped to [0.25, 4].
* @default 1
*/
zoom?: number
/**
* Callback function called when the zoom level changes.
* Receives the new zoom level as an argument.
*/
onZoomChange?: (zoom: number) => void
}
interface PageFormat {
name: string
width: number // Width in pixels
height: number // Height in pixels
margins: {
top: number // Margin in pixels
right: number // Margin in pixels
bottom: number // Margin in pixels
left: number // Margin in pixels
}
}| Option | Type / Values | Default | Description |
|---|---|---|---|
pageFormat | string | PageFormat | 'A4' | Built-in format name or custom page format object |
headerHeight | number (px) | 50 | Header height in pixels |
footerHeight | number (px) | 50 | Footer height in pixels |
pageGap | number (px) | 50 | Gap between pages in pixels |
header | string | fn | '' | Header content; string (supports {page}/{total}) or (pageNumber, totalPages) => string |
footer | string | fn | '{page}' | Footer content; string (supports {page}/{total}) or (pageNumber, totalPages) => string |
pageGapBackground | string (CSS color) | undefined | Background color for page gaps |
onPageFormatChange | fn | () => {} | Callback when page format changes; receives new PageFormat |
zoom | number | 1 | Initial zoom level (0.25–4). See Zoom |
onZoomChange | fn | undefined | Callback when zoom changes; receives new zoom level |
Example usage
Basic configuration with built-in format
import { Pages } from '@tiptap-pro/extension-pages'
const editor = new Editor({
extensions: [
Pages.configure({
pageFormat: 'A4',
headerHeight: 60,
footerHeight: 40,
pageGap: 40,
header: 'My Project',
footer: 'Page {page} of {total}',
pageGapBackground: '#f8f8f8',
}),
],
})Custom page format configuration
import { Pages } from '@tiptap-pro/extension-pages'
const editor = new Editor({
extensions: [
Pages.configure({
pageFormat: {
name: 'Custom Format',
width: 600,
height: 800,
margins: {
top: 40,
right: 30,
bottom: 40,
left: 30,
},
},
header: 'Custom Document',
footer: '{page} / {total}',
onPageFormatChange: (pageFormat) => {
console.log('Page format changed:', pageFormat.name)
// Save user preference, update UI, etc.
},
}),
],
})Available commands
The Pages extension provides the following commands:
| Command | Parameters | Description |
|---|---|---|
setPageFormat | pageFormat: PageFormat | Changes the page format programmatically |
setZoom | zoom: number | Sets the zoom level (clamped to 0.25–4). See Zoom |
Command usage
// Change to built-in format
editor.commands.setPageFormat('Letter')
// Change to custom format
editor.commands.setPageFormat({
id: 'wide-page-format',
width: 1000, // px
height: 700, // px
margins: { top: 20, right: 20, bottom: 20, left: 20 } // px
})Note
The header and footer options accept either a string (with tokens {page} and {total}) or a function (page, total) => string for dynamic content.
Header and footer editor storage
When a header or footer editor overlay is open, the Pages extension exposes the active inner editor through editor.storage.pages. This is useful for custom toolbars, status UI, and listening to editor events inside the header or footer overlay.
| Storage property | Type | Description |
|---|---|---|
activeEditor | Editor | null | Active header/footer inner editor, or null when no overlay is active |
activeEditorType | 'header' | 'footer' | null | Whether the active inner editor belongs to a header or footer |
activePageNumber | number | null | Page number for the active header/footer editor |
headerEditorOn | Editor['on'] | null | Bound event subscription helper for the header inner editor |
headerEditorOff | Editor['off'] | null | Bound event unsubscribe helper for the header inner editor |
footerEditorOn | Editor['on'] | null | Bound event subscription helper for the footer inner editor |
footerEditorOff | Editor['off'] | null | Bound event unsubscribe helper for the footer inner editor |
The headerEditorOn / headerEditorOff and footerEditorOn / footerEditorOff helpers let you subscribe to events from the header and footer editors. These are useful for reacting to events like focus, selection updates, or content changes.
useEffect(() => {
if (!editor) return
const handleFocus = () => {
const { activeEditorType, activePageNumber } = editor.storage.pages
console.log('Editing', activeEditorType, activePageNumber)
}
editor.storage.pages.headerEditorOn?.('focus', handleFocus)
editor.storage.pages.footerEditorOn?.('focus', handleFocus)
return () => {
editor.storage.pages.headerEditorOff?.('focus', handleFocus)
editor.storage.pages.footerEditorOff?.('focus', handleFocus)
}
}, [editor])See Page header and footer for a complete toolbar example.