Markdown hooks cannot access configured extension options
Affected packages
@tiptap/markdown, @tiptap/core
Tiptap Version
3.30.5, reproduced in Node.js through the ESM package exports.
What happened?
parseMarkdown and renderMarkdown cannot access the extension options supplied through .configure(). At runtime, this.options and this.name are undefined. The hook declarations also lack the corresponding this types.
The use case is extension-specific URL handling: configure a URL repair function for parsing and a URL serializer for rendering. These functions need the configured extension's options, without an Editor instance.
Browser Used
Not browser-specific; standalone Node.js.
Reproduction
This deliberately small paragraph extension makes the missing context visible without an editor, browser, or additional extensions:
import { Node } from '@tiptap/core'
import { MarkdownManager } from '@tiptap/markdown'
const Paragraph = Node.create({
name: 'paragraph',
group: 'block',
content: 'inline*',
addOptions() {
return { repairUrl: url => url, serializeMarkdownUrl: url => url }
},
parseMarkdown(token, helpers) {
return helpers.createNode(
this.name,
{ url: this.options.repairUrl(token.text) },
helpers.parseInline(token.tokens),
)
},
renderMarkdown(node) {
return this.options.serializeMarkdownUrl(node.attrs.url)
},
}).configure({
repairUrl: url => `https://example.com/${url}`,
serializeMarkdownUrl: url => `<${url}>`,
})
const manager = new MarkdownManager({ extensions: [Paragraph] })
// Throws: Cannot read properties of undefined (reading 'repairUrl')
manager.parse('asset.png')
// Run independently: throws reading 'serializeMarkdownUrl'.
manager.serialize([{
type: 'paragraph',
attrs: { url: 'https://example.com/asset.png' },
content: [{ type: 'text', text: 'asset.png' }],
}])Expected behavior
Parsing should return:
{
type: 'doc',
content: [{
type: 'paragraph',
attrs: { url: 'https://example.com/asset.png' },
content: [{ type: 'text', text: 'asset.png' }],
}],
}Serialization should return <https://example.com/asset.png>.
Additional context
MarkdownManager.registerExtension resolves both hooks without supplying the extension context. The manager already has the configured extension, so accessing its options should not require an Editor.
A local package patch passes focused ESM checks for configured function options, chained configuration, independent instances, and hooks calling their parent.
Source: ueberdosis/tiptap