@tiptap/extensions
3.32.0 · 13 Oct 2026MIT11.4M / weekRepositoryHomepagenpmAtom feed
109 stable releases, newest first, by release line. Notes are quoted as the maintainers published them.
3.32.0
13 Oct 2026A literal
!directly before a link is now escaped when serializing to Markdown, so the link is no longer parsed back as an image.Update ProseMirror dependencies to their latest versions.
Fix
useEditorStateoverflowing the stack when a selector returns a value with circular references, such aseditor.stateafter one stored mark replaces another.
@tiptap/markdown
Patch Changes
A literal
!directly before a link is now escaped when serializing to Markdown, so the link is no longer parsed back as an image.
@tiptap/pm
Patch Changes
Update ProseMirror dependencies to their latest versions.
@tiptap/react
Patch Changes
Fix
useEditorStateoverflowing the stack when a selector returns a value with circular references, such aseditor.stateafter one stored mark replaces another.
@tiptap/core
Minor Changes
Add the
schemaSpeceditor option to use an external ProseMirror schema structure with local extension behavior.
Patch Changes
Fix list toggling between list types that use different item nodes. Nested lists are recursively converted when the target item schema supports nesting, and flattened into sibling items when it does not.
@tiptap/y-tiptap
Patch Changes
Keep relative text and node positions attached through structural edits, node moves, and undo or redo across collaborating clients.
Improve TypeScript definitions for document synchronization, shared cursors, undo, redo, and document conversions.
Improve collaboration performance and keep comments, highlights, caret positions, and remote caret details intact during remote edits.
Preserve shared content when a client cannot display its nodes or marks, and pause that client's editing until compatible content is available.
Headless document creation rejects empty content when the schema requires child nodes.
@tiptap/extension-collaboration
Patch Changes
Keep collaborative editing, cursor presence, and drag handles compatible with the updated
@tiptap/y-tiptapbinding.
@tiptap/extension-collaboration-caret
Patch Changes
Keep collaborative editing, cursor presence, and drag handles compatible with the updated
@tiptap/y-tiptapbinding.
@tiptap/extension-drag-handle
Patch Changes
Keep collaborative editing, cursor presence, and drag handles compatible with the updated
@tiptap/y-tiptapbinding.
@tiptap/ai-toolkit
Patch Changes
Keep collaborative editing, cursor presence, and drag handles compatible with the updated
@tiptap/y-tiptapbinding.
3.31.4
30 Sep 2026The mathematics extension no longer crashes the editor in older WebKit browsers and WKWebView.
Fix a
TypeErrorthrown when the source editor is destroyed right after dragging content into another editor.splitBlockno longer throwsTransformError: Inserted content deeper than insertion positionwhen the selection spans block boundaries (for example from the start of one paragraph into another block, or across an isolating node). The command now returnsfalsewhen the split is not possible.
@tiptap/extension-mathematics
Patch Changes
The mathematics extension no longer crashes the editor in older WebKit browsers and WKWebView.
@tiptap/core
Patch Changes
Fix a
TypeErrorthrown when the source editor is destroyed right after dragging content into another editor.splitBlockno longer throwsTransformError: Inserted content deeper than insertion positionwhen the selection spans block boundaries (for example from the start of one paragraph into another block, or across an isolating node). The command now returnsfalsewhen the split is not possible.Prevent extra CSS declarations from being rendered from editor content.
Atom block directives (
:::name {…} :::) indented by up to 3 spaces are now tokenized, matching CommonMark indentation rules for block constructs.Numeric HTML entities (
',') are now decoded when parsing markdown, instead of showing up as literal text in the editor.The editor element keeps
role="textbox"aftersetOptions()wheneditorProps.attributesis set. Before, a re-render in React replaced the default role with the user attributes. Attributes passed as a function now get the default role as well.Undoing an input rule restores the Markdown characters that triggered it when using Collaboration.
Bind
parseMarkdownandrenderMarkdownto the configured extension so hooks can readthis.optionsandthis.namewithout an Editor.Pressing Enter before the text of a checked task item now leaves the new empty item unchecked and the item with the text checked. Attributes declared with
keepOnSplit: falsenow reset on the new item, not on the one that keeps the text.Stop joinItemForward and joinItemBackward from joining across isolating nodes.
Node views without a
contentDOMno longer ignore selection mutations, so ProseMirror moves the caret back to a valid position when the browser places it inside the node view.
@tiptap/markdown
Patch Changes
Fix Markdown serialization of inline code containing backticks
Bind
parseMarkdownandrenderMarkdownto the configured extension so hooks can readthis.optionsandthis.namewithout an Editor.
@tiptap/extension-code
Patch Changes
Fix Markdown serialization of inline code containing backticks
@tiptap/extension-table
Patch Changes
Table cells exported to Markdown now escape literal pipe characters, so the cell content survives when the output is read back.
Multi-block table cells no longer leak a U+001F control character into Markdown.
Right-clicking a cell inside a multi-cell table selection no longer collapses that selection.
Prevent extra CSS declarations from being rendered from editor content.
Table cells and headers no longer render the default
colspan="1"androwspan="1"attributes. Cells that actually span still render them, matching how prosemirror-tables serializes spans.
@tiptap/extension-list
Patch Changes
Parsing large Markdown documents that contain ordered lists is much faster. A 578KB document went from about 19s to about 160ms.
@tiptap/extension-collaboration-caret
Patch Changes
Prevent extra CSS declarations from being rendered from editor content.
@tiptap/extension-highlight
Patch Changes
Prevent extra CSS declarations from being rendered from editor content.
@tiptap/extension-text-align
Patch Changes
Prevent extra CSS declarations from being rendered from editor content.
@tiptap/extension-text-style
Patch Changes
Prevent extra CSS declarations from being rendered from editor content.
@tiptap/extension-link
Patch Changes
Typing spaces after a link no longer extends the link, including multiple spaces inserted in one transaction. Formatting changes and undo/redo preserve existing linked whitespace.
@tiptap/react
Patch Changes
Fix Enter and Shift-Enter inside React node views on iOS and Android.
React and Vue now use matching menu extension versions when installed from a specific release.
@tiptap/static-renderer
Patch Changes
Render
<audio>and<video>with a closing tag instead of self-closing them, so browsers no longer nest the following content inside the first audio element.Rendering a node whose
renderHTMLreturns several nested child elements no longer adds stray commas between them in the HTML string output.
@tiptap/extension-collaboration
Patch Changes
Undoing an input rule restores the Markdown characters that triggered it when using Collaboration.
@tiptap/vue-2
Patch Changes
React and Vue now use matching menu extension versions when installed from a specific release.
@tiptap/vue-3
Patch Changes
React and Vue now use matching menu extension versions when installed from a specific release.
3.31.3
4 Sep 2026Fixed a bug which allowed potentially unsafe color values being sent by other clients. Those unsafe colors received from collaboration users are now ignored.
Fix a TypeScript error (TS2694) in the shipped type declarations when
skipLibCheckis turned off.
3.31.2
3 Sep 20263.31.1
3 Sep 2026Fix freezes in framework-based node views on iOS and Android
3.30.6
31 Aug 2026Nested lists exported to Markdown now keep their hierarchy when the file is read back by other Markdown tools.
Nested lists exported to Markdown now keep their hierarchy when the file is read back by other Markdown tools.
Pasting a YouTube iframe without a
srcattribute no longer crashes the editor. The embed is kept without a source.
@tiptap/core
Patch Changes
Nested lists exported to Markdown now keep their hierarchy when the file is read back by other Markdown tools.
@tiptap/extension-list
Patch Changes
Nested lists exported to Markdown now keep their hierarchy when the file is read back by other Markdown tools.
@tiptap/extension-youtube
Patch Changes
Pasting a YouTube iframe without a
srcattribute no longer crashes the editor. The embed is kept without a source.
@tiptap/markdown
Patch Changes
Fix Markdown serialization of whitespace-only marked text.
@tiptap/react
Patch Changes
Reduce overhead in React node views on documents with many nodes.
3.30.5
26 Aug 2026Fix a denial-of-service risk where crafted block or inline Markdown attributes could consume excessive CPU and block the browser or server event loop.
3.30.4
26 Aug 2026Prevent untrusted HTML attributes from changing an object's prototype when merged with
mergeAttributes.
3.30.3
24 Aug 2026Unsetting one text style inside a blockquote no longer removes the other text styles in it.
YouTube live URLs (
/live/<id>) now embed the video.Fix JSX runtime to properly render nested sibling elements by spreading children arrays into DOMOutputSpec
@tiptap/extension-text-style
Patch Changes
Unsetting one text style inside a blockquote no longer removes the other text styles in it.
@tiptap/extension-youtube
Patch Changes
YouTube live URLs (
/live/<id>) now embed the video.
@tiptap/core
Patch Changes
Fix JSX runtime to properly render nested sibling elements by spreading children arrays into DOMOutputSpec
@tiptap/react
Patch Changes
Fix ReactNodeViewRenderer crash when contentComponent is not available
@tiptap/ai-toolkit
Minor Changes
Add the
AiInsertRevealextension (@tiptap/ai-toolkit/streaming-reveal) to fade in text as the AI streams it into a collaborative document.
3.30.2
18 Aug 2026Keep mixed JSX children as separate siblings in DOM output.
Fixed a bug where
editor.chainandeditor.cancan not be accessed on editor initializationFix resizable images staying hidden when the image is cached or fails to load.
3.30.1
13 Aug 2026Fixed table markdown pipe escaping so the extension loads on older Safari and iOS versions (WebKit before Safari 16.4).
Added new ProseMirror helpers that check whether a value is a specific ProseMirror type.
3.30.0
11 Aug 2026ceb0dac: New Decorations API
Finally the decorations API is here! Even though Decorations itself are nothing new in ProseMirror, the new API makes it much easier to use them in Tiptap without leaving your extensions.
Decorations change how the document looks without changing the document itself. Highlighting search results, marking spelling mistakes, showing collaborator cursors, putting a drag handle next to every block.
Until now you had to write a ProseMirror plugin by hand for this, keep the decoration set in plugin state, and map it forward on every transaction. Extensions can now declare decorations directly with a new
addDecorations()hook.addDecorations() { return { create: ({ state }) => // findMatches can be any function that returns an array of { from, to } ranges findMatches(state.doc).map(match => Decoration.Inline(match.from, match.to, { class: 'highlight' }), ), } }There are three kinds.
Decoration.Inline()styles a range of text.Decoration.Node()puts attributes on a block's DOM element.Decoration.Widget()renders your own element at a single position.Every extension that declares decorations is collected into one plugin, so several extensions can decorate the same document without fighting over it.
Doing less work on every keystroke
By default decorations are rebuilt whenever the document changes. That is fine for small documents and wasteful for large ones, so there are two ways to narrow it down.
shouldUpdate()skips transactions you do not care about. If your decorations only depend on headings, ignore everything else.update: 'changedRanges'together withcreateInRange()only rescans the blocks that actually changed. On a long document this is the difference between scanning the whole thing on every keystroke and scanning one paragraph.For decorations driven by data outside the editor, like comments loaded from a server, use
update: 'manual'and refresh them yourself witheditor.commands.updateDecorations().React and Vue components as widgets
ReactWidgetRendererandVueWidgetRendererrender a real component into a widget decoration, inside your existing app context. Providers, context and stores work as usual.Widgets take a
key. Reuse the same key and the component instance stays mounted while the document changes around it, so local state such as an open menu, a counter or a half-typed input survives editing. Use a stable id from your own data, not a position or a list index, otherwise the component remounts and loses that state.Widgets also accept the ProseMirror options
side,relaxedSide,stopEventandignoreSelection.Documentation
ceb0dac: Fix FloatingMenu not registering when the editor prop is provided synchronously, which prevented the menu from appearing
ceb0dac:
ListKeymapnow registers aTabshortcut that sinks a top-level textblock into the previous list's last item. Pressing Tab at the start of a paragraph right after a bullet/ordered/task list moves the paragraph inside the last list item. The handler does nothing when the cursor is already inside a list item (sinkListItemkeeps working), when there is no list before the paragraph, when the caret is mid-textblock, or when the selection is not a text selection (for example a gap cursor).@tiptap/corealso exposes a newgetPreviousBlockSibling($pos)helper that returns the block-level sibling before the cursor's textblock, or null at the first child of the block parent.
@tiptap/vue-2
Minor Changes
ceb0dac: New Decorations API
Finally the decorations API is here! Even though Decorations itself are nothing new in ProseMirror, the new API makes it much easier to use them in Tiptap without leaving your extensions.
Decorations change how the document looks without changing the document itself. Highlighting search results, marking spelling mistakes, showing collaborator cursors, putting a drag handle next to every block.
Until now you had to write a ProseMirror plugin by hand for this, keep the decoration set in plugin state, and map it forward on every transaction. Extensions can now declare decorations directly with a new
addDecorations()hook.addDecorations() { return { create: ({ state }) => // findMatches can be any function that returns an array of { from, to } ranges findMatches(state.doc).map(match => Decoration.Inline(match.from, match.to, { class: 'highlight' }), ), } }There are three kinds.
Decoration.Inline()styles a range of text.Decoration.Node()puts attributes on a block's DOM element.Decoration.Widget()renders your own element at a single position.Every extension that declares decorations is collected into one plugin, so several extensions can decorate the same document without fighting over it.
Doing less work on every keystroke
By default decorations are rebuilt whenever the document changes. That is fine for small documents and wasteful for large ones, so there are two ways to narrow it down.
shouldUpdate()skips transactions you do not care about. If your decorations only depend on headings, ignore everything else.update: 'changedRanges'together withcreateInRange()only rescans the blocks that actually changed. On a long document this is the difference between scanning the whole thing on every keystroke and scanning one paragraph.For decorations driven by data outside the editor, like comments loaded from a server, use
update: 'manual'and refresh them yourself witheditor.commands.updateDecorations().React and Vue components as widgets
ReactWidgetRendererandVueWidgetRendererrender a real component into a widget decoration, inside your existing app context. Providers, context and stores work as usual.Widgets take a
key. Reuse the same key and the component instance stays mounted while the document changes around it, so local state such as an open menu, a counter or a half-typed input survives editing. Use a stable id from your own data, not a position or a list index, otherwise the component remounts and loses that state.Widgets also accept the ProseMirror options
side,relaxedSide,stopEventandignoreSelection.Documentation
Patch Changes
ceb0dac: Fix FloatingMenu not registering when the editor prop is provided synchronously, which prevented the menu from appearing
@tiptap/extension-list
Minor Changes
ceb0dac:
ListKeymapnow registers aTabshortcut that sinks a top-level textblock into the previous list's last item. Pressing Tab at the start of a paragraph right after a bullet/ordered/task list moves the paragraph inside the last list item. The handler does nothing when the cursor is already inside a list item (sinkListItemkeeps working), when there is no list before the paragraph, when the caret is mid-textblock, or when the selection is not a text selection (for example a gap cursor).@tiptap/corealso exposes a newgetPreviousBlockSibling($pos)helper that returns the block-level sibling before the cursor's textblock, or null at the first child of the block parent.
Patch Changes
ceb0dac: Parse block math that follows an ordered list item without a blank line, both after the list and indented inside the item, instead of pulling it into the item's text.
ceb0dac: TaskItem: the checkbox label now also fills the wrapping label element, so accessibility audits no longer flag it as empty.
@tiptap/core
Minor Changes
ceb0dac:
ListKeymapnow registers aTabshortcut that sinks a top-level textblock into the previous list's last item. Pressing Tab at the start of a paragraph right after a bullet/ordered/task list moves the paragraph inside the last list item. The handler does nothing when the cursor is already inside a list item (sinkListItemkeeps working), when there is no list before the paragraph, when the caret is mid-textblock, or when the selection is not a text selection (for example a gap cursor).@tiptap/corealso exposes a newgetPreviousBlockSibling($pos)helper that returns the block-level sibling before the cursor's textblock, or null at the first child of the block parent.ceb0dac: New Decorations API
Finally the decorations API is here! Even though Decorations itself are nothing new in ProseMirror, the new API makes it much easier to use them in Tiptap without leaving your extensions.
Decorations change how the document looks without changing the document itself. Highlighting search results, marking spelling mistakes, showing collaborator cursors, putting a drag handle next to every block.
Until now you had to write a ProseMirror plugin by hand for this, keep the decoration set in plugin state, and map it forward on every transaction. Extensions can now declare decorations directly with a new
addDecorations()hook.addDecorations() { return { create: ({ state }) => // findMatches can be any function that returns an array of { from, to } ranges findMatches(state.doc).map(match => Decoration.Inline(match.from, match.to, { class: 'highlight' }), ), } }There are three kinds.
Decoration.Inline()styles a range of text.Decoration.Node()puts attributes on a block's DOM element.Decoration.Widget()renders your own element at a single position.Every extension that declares decorations is collected into one plugin, so several extensions can decorate the same document without fighting over it.
Doing less work on every keystroke
By default decorations are rebuilt whenever the document changes. That is fine for small documents and wasteful for large ones, so there are two ways to narrow it down.
shouldUpdate()skips transactions you do not care about. If your decorations only depend on headings, ignore everything else.update: 'changedRanges'together withcreateInRange()only rescans the blocks that actually changed. On a long document this is the difference between scanning the whole thing on every keystroke and scanning one paragraph.For decorations driven by data outside the editor, like comments loaded from a server, use
update: 'manual'and refresh them yourself witheditor.commands.updateDecorations().React and Vue components as widgets
ReactWidgetRendererandVueWidgetRendererrender a real component into a widget decoration, inside your existing app context. Providers, context and stores work as usual.Widgets take a
key. Reuse the same key and the component instance stays mounted while the document changes around it, so local state such as an open menu, a counter or a half-typed input survives editing. Use a stable id from your own data, not a position or a list index, otherwise the component remounts and loses that state.Widgets also accept the ProseMirror options
side,relaxedSide,stopEventandignoreSelection.Documentation
Patch Changes
ceb0dac: Fixed
insertContent,insertContentAtandsetContentfailing when prosemirror-model is loaded more than once.
@tiptap/starter-kit
Patch Changes
ceb0dac: StarterKit now pins its bundled
@tiptap/*dependencies to the exact version it was released with, so installing a specific StarterKit version gives you that version's extension set instead of the newest one.
@tiptap/react
Minor Changes
ceb0dac: New Decorations API
Finally the decorations API is here! Even though Decorations itself are nothing new in ProseMirror, the new API makes it much easier to use them in Tiptap without leaving your extensions.
Decorations change how the document looks without changing the document itself. Highlighting search results, marking spelling mistakes, showing collaborator cursors, putting a drag handle next to every block.
Until now you had to write a ProseMirror plugin by hand for this, keep the decoration set in plugin state, and map it forward on every transaction. Extensions can now declare decorations directly with a new
addDecorations()hook.addDecorations() { return { create: ({ state }) => // findMatches can be any function that returns an array of { from, to } ranges findMatches(state.doc).map(match => Decoration.Inline(match.from, match.to, { class: 'highlight' }), ), } }There are three kinds.
Decoration.Inline()styles a range of text.Decoration.Node()puts attributes on a block's DOM element.Decoration.Widget()renders your own element at a single position.Every extension that declares decorations is collected into one plugin, so several extensions can decorate the same document without fighting over it.
Doing less work on every keystroke
By default decorations are rebuilt whenever the document changes. That is fine for small documents and wasteful for large ones, so there are two ways to narrow it down.
shouldUpdate()skips transactions you do not care about. If your decorations only depend on headings, ignore everything else.update: 'changedRanges'together withcreateInRange()only rescans the blocks that actually changed. On a long document this is the difference between scanning the whole thing on every keystroke and scanning one paragraph.For decorations driven by data outside the editor, like comments loaded from a server, use
update: 'manual'and refresh them yourself witheditor.commands.updateDecorations().React and Vue components as widgets
ReactWidgetRendererandVueWidgetRendererrender a real component into a widget decoration, inside your existing app context. Providers, context and stores work as usual.Widgets take a
key. Reuse the same key and the component instance stays mounted while the document changes around it, so local state such as an open menu, a counter or a half-typed input survives editing. Use a stable id from your own data, not a position or a list index, otherwise the component remounts and loses that state.Widgets also accept the ProseMirror options
side,relaxedSide,stopEventandignoreSelection.Documentation
Patch Changes
ceb0dac: React node views no longer show the selected state when the selection covers a position the node view has moved away from.
@tiptap/markdown
Patch Changes
ceb0dac: Markdown with inline HTML such as an unclosed
<b>tag no longer parses into an invalid document. The tag is dropped and its text is kept.
@tiptap/static-renderer
Patch Changes
ceb0dac: Fixed table cell and header spans in the React static renderer.
@tiptap/pm
Patch Changes
ceb0dac: Fix the
./schema-listexport map pointingtypesatdist/schema/, which is not emitted. Tools that read thetypescondition directly could not resolve@tiptap/pm/schema-list.
@tiptap/extension-table
Patch Changes
ceb0dac: Deleting the last row or column of a table no longer moves the cursor outside the table when there is content below it.
@tiptap/extension-drag-handle-react
Patch Changes
ceb0dac: Fixed the React
DragHandlebreaking drag-and-drop whenonNodeChangeis an inline callback, by no longer re-registering its plugin when a callback's identity changes.
@tiptap/extension-mathematics
Patch Changes
ceb0dac: Allow KaTeX 0.18 to be installed with the math extension
@tiptap/extension-blockquote
Patch Changes
ceb0dac: Fixed Backspace freezing after merging a paragraph into a blockquote.
@tiptap/vue-3
Minor Changes
ceb0dac: New Decorations API
Finally the decorations API is here! Even though Decorations itself are nothing new in ProseMirror, the new API makes it much easier to use them in Tiptap without leaving your extensions.
Decorations change how the document looks without changing the document itself. Highlighting search results, marking spelling mistakes, showing collaborator cursors, putting a drag handle next to every block.
Until now you had to write a ProseMirror plugin by hand for this, keep the decoration set in plugin state, and map it forward on every transaction. Extensions can now declare decorations directly with a new
addDecorations()hook.addDecorations() { return { create: ({ state }) => // findMatches can be any function that returns an array of { from, to } ranges findMatches(state.doc).map(match => Decoration.Inline(match.from, match.to, { class: 'highlight' }), ), } }There are three kinds.
Decoration.Inline()styles a range of text.Decoration.Node()puts attributes on a block's DOM element.Decoration.Widget()renders your own element at a single position.Every extension that declares decorations is collected into one plugin, so several extensions can decorate the same document without fighting over it.
Doing less work on every keystroke
By default decorations are rebuilt whenever the document changes. That is fine for small documents and wasteful for large ones, so there are two ways to narrow it down.
shouldUpdate()skips transactions you do not care about. If your decorations only depend on headings, ignore everything else.update: 'changedRanges'together withcreateInRange()only rescans the blocks that actually changed. On a long document this is the difference between scanning the whole thing on every keystroke and scanning one paragraph.For decorations driven by data outside the editor, like comments loaded from a server, use
update: 'manual'and refresh them yourself witheditor.commands.updateDecorations().React and Vue components as widgets
ReactWidgetRendererandVueWidgetRendererrender a real component into a widget decoration, inside your existing app context. Providers, context and stores work as usual.Widgets take a
key. Reuse the same key and the component instance stays mounted while the document changes around it, so local state such as an open menu, a counter or a half-typed input survives editing. Use a stable id from your own data, not a position or a list index, otherwise the component remounts and loses that state.Widgets also accept the ProseMirror options
side,relaxedSide,stopEventandignoreSelection.Documentation
3.29.2
28 Jul 2026Fixed the caret jumping back to the previous block when pressing Enter inside a React node view.
Ensure only the active find-and-replace result keeps the current-result highlight while navigating matches.
3.29.0
24 Jul 2026Add official RubyText extension for HTML ruby text annotations with non-editable annotations and mark-based document storage. The click-to-edit annotation editor can be replaced with a custom element via the
renderAnnotationEditoroption.Fix a TypeScript build error in
isAndroid()where comparingnavigator.platformagainst the literal'Android'with===could fail to compile under somelib.dom.d.tstypings ("types have no overlap"). Switched to the same.includes()pattern already used byisiOS(), which is not affected by this TypeScript narrowing issue. No runtime behavior change.Fixed a bug where deleting an
AllSelection(for example right after Ctrl/Cmd+A) left a lingering "phantom" selection highlight over the emptied document instead of a text cursor.deleteSelectionnow collapses the selection to a cursor.
@tiptap/extension-ruby-text
Minor Changes
Add official RubyText extension for HTML ruby text annotations with non-editable annotations and mark-based document storage. The click-to-edit annotation editor can be replaced with a custom element via the
renderAnnotationEditoroption.
@tiptap/core
Patch Changes
Fix a TypeScript build error in
isAndroid()where comparingnavigator.platformagainst the literal'Android'with===could fail to compile under somelib.dom.d.tstypings ("types have no overlap"). Switched to the same.includes()pattern already used byisiOS(), which is not affected by this TypeScript narrowing issue. No runtime behavior change.Fixed a bug where deleting an
AllSelection(for example right after Ctrl/Cmd+A) left a lingering "phantom" selection highlight over the emptied document instead of a text cursor.deleteSelectionnow collapses the selection to a cursor.Fix input rules crashing when the matched text spans an inline atom node like a mention.
Node view
getPos()now returnsundefinedinstead of throwing when the position cannot be resolved yet, for example when React 19 renders a node view component while the editor view is still updating.Fixed
onContentErrorthrowing when callingeditor.commandsfrom inside the handler on initial load with invalid content. The editor now has a usable state (seeded from the stripped fallback document) beforeonContentErrorfires.Fix
editor.$pos()returning the wrong node inside container nodes, for example the list item instead of the list.Add
insertDefaultBlockto insert the default textblock allowed at a position. It accepts an optional position, attributes, content, and selection-update option.
@tiptap/extension-find-and-replace
Minor Changes
Added a new
@tiptap/extension-find-and-replaceextension. It searches the document for a term, highlights all matches with decorations, and replaces the current or all matches. Supports case-sensitive, whole-word, and RE2-compatible regex search, plus commands to jump between results. Regex search avoids catastrophic backtracking but does not support lookarounds or backreferences.
@tiptap/pm
Patch Changes
Bump
prosemirror-modelto^1.25.11, fixing pasting content copied from the editor inserting extra empty paragraphs (a regression introduced inprosemirror-view1.42.0).
@tiptap/extension-hard-break
Patch Changes
Fixed a bug where inserted hard breaks would not scroll the view on insertion via commands.
@tiptap/extension-code-block
Patch Changes
Fixed a bug where pressing
ArrowUpin a code block that is the first node in the document did nothing, leaving no way to insert content above it. A new default block is now inserted above the code block, mirroring the existingArrowDownbehavior. The behavior can be disabled via the newexitOnArrowUpoption.
@tiptap/extension-table
Patch Changes
Fix inserting a table with an empty cell or header (e.g. via
insertContent/insertContentAt) throwingRangeError: Invalid content for node tableCell/tableHeader: <>. Empty<td>/<th>elements are now backfilled with the cell's default block content, matching the behavior you already get fromsetContent.Keep line breaks inside table cells when serializing to markdown. Hard breaks and paragraph breaks in a cell are now written as
<br>instead of being collapsed into a space, so they survive a parse/serialize round trip.
@tiptap/markdown
Patch Changes
Fixed blank lines being dropped after block elements (headings, tables, etc.) when parsing markdown. Blank lines were being absorbed into the block token instead of being preserved, causing content to lose a blank line on each parse/serialize cycle.
@tiptap/react
Patch Changes
Fixed
useEditorStatenot re-rendering components wheneditor.setEditable()changes the editor's editable state, since that call only emits anupdateevent and never atransaction.
@tiptap/vue-3
Patch Changes
Fix
<node-view-content as="tbody">(and similar restricted-content elements) rendering with an extra wrapper<div>nested inside them, which broke tables in Vue node views. Note: keep<node-view-content>mounted (usev-show, notv-if) — conditionally remounting it can leave ProseMirror attached to the old element.
@tiptap/extension-image
Patch Changes
Fix resizable images not synchronizing rendered attributes after updates
@tiptap/static-renderer
Patch Changes
Fix Markdown table serialization for merged cells by preserving the correct column layout for rowspan and colspan.
@tiptap/extension-link
Minor Changes
Typing or pasting Markdown link syntax like
[Tiptap](https://tiptap.dev)or[Tiptap](https://tiptap.dev "Rich text editor")can now automatically be converted into a link. The behavior is opt-in, enable it with the newmarkdownLinksoption.
3.28.0
15 Jul 2026Reading the note…
3.27.4
13 Jul 2026Reading the note…
3.27.3
7 Jul 2026Reading the note…
3.27.2
6 Jul 2026Reading the note…
3.27.1
18 Jun 2026Reading the note…
3.27.0
17 Jun 2026Reading the note…
3.26.1
11 Jun 2026Reading the note…
3.26.0
5 Jun 2026Reading the note…
3.25.0
3 Jun 2026Reading the note…
3.24.0
29 May 2026Reading the note…
3.23.6
21 May 2026Reading the note…
3.23.5
19 May 2026Reading the note…
3.23.4
13 May 2026Reading the note…
3.23.2
12 May 2026Reading the note…
3.23.1
8 May 2026Reading the note…
3.22.5
28 Apr 2026Reading the note…
3.22.4
18 Apr 2026Reading the note…
3.22.3
8 Apr 2026Reading the note…
3.22.2
4 Apr 2026Reading the note…
3.22.1
2 Apr 2026Reading the note…
3.22.0
31 Mar 2026Reading the note…
3.21.0
27 Mar 2026Reading the note…
3.20.6
27 Mar 2026Reading the note…
3.20.5
24 Mar 2026Reading the note…
3.20.4
17 Mar 2026Reading the note…
3.20.3
16 Mar 2026Reading the note…
3.20.2
15 Mar 2026Reading the note…
3.20.1
6 Mar 2026Reading the note…
3.20.0
18 Feb 2026Reading the note…
3.19.0
3 Feb 2026Reading the note…
3.18.0
28 Jan 2026Reading the note…
3.17.1
24 Jan 2026Reading the note…
3.17.0
23 Jan 2026Reading the note…
3.16.0
20 Jan 2026Reading the note…