Export ODT from your editor
Use Tiptap's @tiptap-pro/extension-export-odt to export your editor's content as an .odt file. This extension integrates ODT export functionality into your editor by sending the document to the Tiptap convert service for conversion.
You can also use the REST API instead if you'd prefer to handle the conversion on your end.
Install the ODT Export extension
The Conversion extensions are published in Tiptap's private npm registry. Integrate the extensions by following the private registry guide.
Once done you can install and import the Export ODT extension package.
npm i @tiptap-pro/extension-export-odtimport { ExportOdt } from '@tiptap-pro/extension-export-odt'Configuring the extension
The ExportOdt extension can be configured with an ExportOdtOptions (object) as an argument to the configure method with the following properties:
import { ExportOdt } from '@tiptap-pro/extension-export-odt'
const editor = new Editor({
extensions: [
// Other extensions ...
ExportOdt.configure({
endpoint: 'https://api.tiptap.dev/v2/convert',
token: 'YOUR_TOKEN',
appId: 'YOUR_APP_ID',
styleOverrides: {},
headers: {},
footers: {},
pageSize: { width: '21cm', height: '29.7cm' },
pageMargins: { top: '1cm', bottom: '1cm', left: '1cm', right: '1cm' },
customNodes: [],
onCompleteExport: (result) => {
// Handle the exported Blob
},
}),
// Other extensions ...
],
})| Parameter | Type | Description | Default |
|---|---|---|---|
endpoint | string | The Tiptap API endpoint for conversion | 'https://api.tiptap.dev/v2/convert' |
token | string | The Tiptap JWT for authentication | '' |
appId | string | The Tiptap App ID for authentication | '' |
styleOverrides | Record<string, string> | Style overrides to apply to the export | undefined |
headers | HeaderConfig | Header configuration for the exported document | undefined |
footers | FooterConfig | Footer configuration for the exported document | undefined |
pageSize | PageSize | Page size configuration | undefined |
pageMargins | PageMargins | Page margins configuration | undefined |
customNodes | CustomNodeDefinition[] | Custom node definitions for DOCX-based conversion (requires @tiptap-pro/extension-export-docx) | undefined |
onCompleteExport | (result: Blob) => void | Callback that receives the exported file as a Blob | Throws error if not provided |
HeaderConfig
| Property | Type | Description |
|---|---|---|
evenAndOddHeaders | boolean | Whether to use different headers for odd and even pages |
differentFirstPage | boolean | Whether to use a different header on the first page. When true, the first value is used on page one instead of default. |
default | string | The standard default header on every page, or header on odd pages when evenAndOddHeaders is active. Accepts a plain text string or stringified Tiptap JSONContent for rich formatting. |
first | string | The header on the first page. Only used when differentFirstPage is set to true. Accepts a plain text string or stringified Tiptap JSONContent for rich formatting. |
even | string | The header on even pages when the evenAndOddHeaders option is activated. Accepts a plain text string or stringified Tiptap JSONContent for rich formatting. |
FooterConfig
| Property | Type | Description |
|---|---|---|
evenAndOddFooters | boolean | Whether to use different footers for odd and even pages |
differentFirstPage | boolean | Whether to use a different footer on the first page. When true, the first value is used on page one instead of default. |
default | string | The standard default footer on every page, or footer on odd pages when evenAndOddFooters is active. Accepts a plain text string or stringified Tiptap JSONContent for rich formatting. |
first | string | The footer on the first page. Only used when differentFirstPage is set to true. Accepts a plain text string or stringified Tiptap JSONContent for rich formatting. |
even | string | The footer on even pages when the evenAndOddFooters option is activated. Accepts a plain text string or stringified Tiptap JSONContent for rich formatting. |
PageSize
| Property | Type | Description | Default |
|---|---|---|---|
width | string | The width of the page. Must be a positive number followed by a valid unit (cm, in, pt, pc, mm, px). | "21cm" |
height | string | The height of the page. Must be a positive number followed by a valid unit (cm, in, pt, pc, mm, px). | "29.7cm" |
PageMargins
| Property | Type | Description | Default |
|---|---|---|---|
top | string | The top margin of the page. Can be negative. Must be a number followed by a valid unit (cm, in, pt, pc, mm, px). | "1cm" |
bottom | string | The bottom margin of the page. Can be negative. Must be a number followed by a valid unit (cm, in, pt, pc, mm, px). | "1cm" |
left | string | The left margin of the page. Must be a positive number followed by a valid unit (cm, in, pt, pc, mm, px). | "1cm" |
right | string | The right margin of the page. Must be a positive number followed by a valid unit (cm, in, pt, pc, mm, px). | "1cm" |
Export an ODT file
With the extension installed, you can export your editor's content to .odt using the exportOdt command.
/**
* Export the current document as an ODT file via the Tiptap convert service.
*
* @param options - All extension-level options can be overridden per-invocation
* @example editor.commands.exportOdt({ onCompleteExport: (result) => {} })
*/
exportOdt: (options?: ExportOdtCommandOptions) => ReturnTypeThe ExportOdtCommandOptions interface extends ExportOdtOptions, so every configuration option can be overridden per-command invocation:
| Property | Type | Description |
|---|---|---|
endpoint | string | Override the API endpoint for this specific export |
token | string | Override the JWT token for this specific export |
appId | string | Override the App ID for this specific export |
styleOverrides | Record<string, string> | Override style overrides for this specific export |
headers | HeaderConfig | Override header configuration for this specific export |
footers | FooterConfig | Override footer configuration for this specific export |
pageSize | PageSize | Override page size for this specific export |
pageMargins | PageMargins | Override page margins for this specific export |
customNodes | CustomNodeDefinition[] | Override custom node definitions for this specific export |
onCompleteExport | (result: Blob) => void | Override the callback for this specific export |
import { ExportOdt } from '@tiptap-pro/extension-export-odt'
const editor = new Editor({
extensions: [
// Other extensions ...
ExportOdt.configure({
token: 'YOUR_TOKEN',
appId: 'YOUR_APP_ID',
onCompleteExport(result) {
// Download the ODT file
const url = URL.createObjectURL(result)
const a = document.createElement('a')
a.href = url
a.download = 'document.odt'
a.click()
URL.revokeObjectURL(url)
},
}),
// Other extensions ...
],
})
// Use the extension-level callback
editor.chain().exportOdt().run()
// Or override options for a specific export
editor
.chain()
.exportOdt({
pageSize: { width: '8.5in', height: '11in' },
onCompleteExport(result) {
// Custom handling for this specific export
const url = URL.createObjectURL(result)
window.open(url)
},
})
.run()How it works
When you call exportOdt, the extension sends the editor's document and any configured options (style overrides, page layout, headers, footers) to the Convert service, which returns the resulting .odt file as a binary blob. The onCompleteExport callback receives the blob directly. Errors are thrown as exceptions rather than passed through the callback.
What to expect
- Authentication required (
tokenJWT andappId). Generate JWTs server-side. See the Conversion install guide. - HTTP responses to handle:
401(missing or invalid JWT),403(operation not permitted for your app — typically a format your plan doesn't include),5xx(transient server-side error; retry with backoff). - Each request is processed end-to-end before responding. Plan for longer round-trips on large documents.
What not to expect
- Round-trip identity with Word. ODT is the OpenDocument Text format used by LibreOffice and OpenOffice; some Word-specific header/footer features and styling quirks may not survive export.
- Pixel-perfect Word-to-ODT layout match. Use ODT when you want a portable open-format file; use DOCX when fidelity to Word is the priority.
Support & Limitations
| Feature | Support |
|---|---|
| Text content | ✓ Basic text, spacing, punctuation |
| Text formatting | ✓ Bold, italic, underline, strikethrough, alignment, line height |
| Block elements | ✓ Paragraphs, headings (1–6), blockquotes, ordered and unordered lists |
| Tables | ✓ Basic structure, header rows, colspan |
| Links | ✓ Hyperlinks |
| Media (Images) | ✓ Embedded images, size preserved |
| Styles | ✓ Font families*, Font colors, font sizes, background colors, line heights |
| Headers & Footers | ✓ |
| Math | ✓ |
| Page Breaks | ✓ |
| Sections | ✗ |
| Footnotes & Endnotes | ✗ |
| Comments & Revisions | ✗ |
| Table of Contents | ✗ |
| Advanced Formatting | ✗ Columns, text direction, forms, macros, embedded scripts |
| Metadata | ✗ |
| Text Boxes, Shapes, SmartArt | ✗ |
- Font families are supported as long as the target font is installed on the operative system when the exported file is opened.
For a detailed per-feature breakdown, see the Supported features matrix. Note that element overrides (paragraphOverrides, textRunOverrides, tableOverrides, tableCellOverrides, imageOverrides) available in the DOCX export extension are not passed through to the ODT conversion.