From 835caf5c49a274fba6e4b748d6279c38e845e573 Mon Sep 17 00:00:00 2001
From: bdbch <6538827+bdbch@users.noreply.github.com>
Date: Tue, 19 May 2026 11:41:10 +0200
Subject: [PATCH 1/5] fix(core): fix $pos() returning doc for non-text atom
nodes (#7841)
* fix(core): return correct node from for non-text atom nodes
* fix(core): return correct node from $pos() for non-text atom nodes
* fix(core): return correct node from $pos() for non-text block atom nodes
---
.changeset/fix-pos-non-text-nodes.md | 6 +++
packages/core/__tests__/nodePos.spec.ts | 71 +++++++++++++++++++++++++
packages/core/src/Editor.ts | 11 +++-
3 files changed, 86 insertions(+), 2 deletions(-)
create mode 100644 .changeset/fix-pos-non-text-nodes.md
diff --git a/.changeset/fix-pos-non-text-nodes.md b/.changeset/fix-pos-non-text-nodes.md
new file mode 100644
index 0000000000..2ec21427e2
--- /dev/null
+++ b/.changeset/fix-pos-non-text-nodes.md
@@ -0,0 +1,6 @@
+---
+"@tiptap/core": patch
+---
+
+Fix $pos() returning correct node for non-text atom nodes instead of doc node
+
diff --git a/packages/core/__tests__/nodePos.spec.ts b/packages/core/__tests__/nodePos.spec.ts
index b1edf5e78f..5e97a2bdbb 100644
--- a/packages/core/__tests__/nodePos.spec.ts
+++ b/packages/core/__tests__/nodePos.spec.ts
@@ -35,6 +35,32 @@ const CustomInlineNode = Node.create({
},
})
+const CustomBlockAtomNode = Node.create({
+ name: 'customBlockAtom',
+ group: 'block',
+ atom: true,
+
+ addAttributes() {
+ return {
+ id: {
+ default: null,
+ },
+ }
+ },
+
+ parseHTML() {
+ return [
+ {
+ tag: 'div[data-type="custom-block-atom"]',
+ },
+ ]
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return ['div', { 'data-type': 'custom-block-atom', ...HTMLAttributes }]
+ },
+})
+
describe('NodePos', () => {
let editor: Editor
@@ -503,6 +529,51 @@ describe('NodePos', () => {
})
})
+ describe('$pos', () => {
+ it('should return the correct node when pointing at a non-text atom node', () => {
+ editor = new Editor({
+ extensions: [Document, Paragraph, Text, CustomInlineNode],
+ content: '
',
+ })
+
+ const inlineNode = editor.$node('customInline')
+
+ expect(inlineNode).not.toBeNull()
+
+ const nodeAtPos = editor.$pos(inlineNode!.pos)
+
+ expect(nodeAtPos.node.type.name).toBe('customInline')
+ expect(nodeAtPos.node.type.name).not.toBe('doc')
+ })
+
+ it('should return doc node when resolving pos 0', () => {
+ editor = new Editor({
+ extensions: [Document, Paragraph, Text],
+ content: 'Hello
',
+ })
+
+ const docPos = editor.$pos(0)
+
+ expect(docPos.node.type.name).toBe('doc')
+ })
+
+ it('should return the top-level block atom node for positions before non-text block atoms', () => {
+ editor = new Editor({
+ extensions: [Document, Paragraph, Text, CustomBlockAtomNode],
+ content: 'Before
',
+ })
+
+ const blockAtom = editor.$node('customBlockAtom')
+
+ expect(blockAtom).not.toBeNull()
+
+ const nodeAtPos = editor.$pos(blockAtom!.pos)
+
+ expect(nodeAtPos.node.type.name).toBe('customBlockAtom')
+ expect(nodeAtPos.node.type.name).not.toBe('doc')
+ })
+ })
+
describe('$doc', () => {
it('should correctly traverse $doc children', () => {
editor = new Editor({
diff --git a/packages/core/src/Editor.ts b/packages/core/src/Editor.ts
index 415c034d20..0d87a0b464 100644
--- a/packages/core/src/Editor.ts
+++ b/packages/core/src/Editor.ts
@@ -804,8 +804,15 @@ export class Editor extends EventEmitter {
public $pos(pos: number) {
const $pos = this.state.doc.resolve(pos)
-
- return new NodePos($pos, this)
+ // When the position sits directly before a non-text node (e.g. an image or
+ // other atom), nodeAfter is that node but resolvedPos.node() would return
+ // the parent (often the doc at depth 0). Pass nodeAfter as the explicit node
+ // so NodePos.node returns the expected node instead of the parent.
+ // Keep $pos(0) returning the doc node; for other positions, prefer nodeAfter
+ // when it points at a non-text node.
+ const node = pos > 0 && $pos.nodeAfter && !$pos.nodeAfter.isText ? $pos.nodeAfter : null
+
+ return new NodePos($pos, this, false, node)
}
get $doc() {
From 95e138c18807f2d31c7ef83b3762ae654c8c8243 Mon Sep 17 00:00:00 2001
From: bdbch <6538827+bdbch@users.noreply.github.com>
Date: Tue, 19 May 2026 11:53:52 +0200
Subject: [PATCH 2/5] fix(nodeview): eliminate unnecessary re-renders, add
opt-in position tracking (#7828)
* fix(nodeview): optimize NodeView re-renders by implementing shallow prop comparison
* fix(nodeview): eliminate unnecessary re-renders, add opt-in position tracking
NodeViews no longer re-render when decorations or position change without
content changes. Added trackNodeViewPosition option for reactive position
prop. Removed internal nodeViewPositionRegistry. Added shallow prop
comparison in ReactRenderer.updateProps().
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* refactor: remove position prop, use getPos() as re-render trigger
Instead of a separate reactive position prop, the trackNodeViewPosition
option now triggers a re-render via getPos reference change. Users always
use getPos() for position access.
* fix: address Copilot review comments
- Fix JSDoc for trackNodeViewPosition (no reactive position prop)
- Call updateElementAttributes() in handlePositionUpdate
- Only compute newPos in the nodeChanged branch
* fix(vue): restore decoration class updates when node reference unchanged
* fix(vue): sync currentPos in node-changed branch to prevent double re-render
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---
.changeset/hip-penguins-juggle.md | 14 ++
.../recommendation/Recommendation.jsx | 4 +-
.../recommendation/Recommendation.js | 4 +-
.../Decorations/React/Component.tsx | 33 ++++
.../Decorations/React/Extension.ts | 74 +++++++++
.../Decorations/React/index.html | 0
.../Decorations/React/index.tsx | 28 ++++
.../Decorations/React/styles.scss | 147 ++++++++++++++++++
.../Decorations/Vue/Component.vue | 107 +++++++++++++
.../Decorations/Vue/Extension.js | 74 +++++++++
.../GuideNodeViews/Decorations/Vue/index.html | 0
.../GuideNodeViews/Decorations/Vue/index.vue | 138 ++++++++++++++++
packages/core/src/types.ts | 9 ++
packages/core/src/utilities/index.ts | 1 -
.../src/utilities/nodeViewPositionRegistry.ts | 70 ---------
packages/react/src/ReactNodeViewRenderer.tsx | 104 ++++++-------
packages/react/src/ReactRenderer.tsx | 18 +++
packages/vue-2/src/VueNodeViewRenderer.ts | 115 +++++++-------
packages/vue-3/src/VueNodeViewRenderer.ts | 119 +++++++-------
19 files changed, 822 insertions(+), 237 deletions(-)
create mode 100644 .changeset/hip-penguins-juggle.md
create mode 100644 demos/src/GuideNodeViews/Decorations/React/Component.tsx
create mode 100644 demos/src/GuideNodeViews/Decorations/React/Extension.ts
create mode 100644 demos/src/GuideNodeViews/Decorations/React/index.html
create mode 100644 demos/src/GuideNodeViews/Decorations/React/index.tsx
create mode 100644 demos/src/GuideNodeViews/Decorations/React/styles.scss
create mode 100644 demos/src/GuideNodeViews/Decorations/Vue/Component.vue
create mode 100644 demos/src/GuideNodeViews/Decorations/Vue/Extension.js
create mode 100644 demos/src/GuideNodeViews/Decorations/Vue/index.html
create mode 100644 demos/src/GuideNodeViews/Decorations/Vue/index.vue
delete mode 100644 packages/core/src/utilities/nodeViewPositionRegistry.ts
diff --git a/.changeset/hip-penguins-juggle.md b/.changeset/hip-penguins-juggle.md
new file mode 100644
index 0000000000..d0e63bf6d0
--- /dev/null
+++ b/.changeset/hip-penguins-juggle.md
@@ -0,0 +1,14 @@
+---
+"@tiptap/core": patch
+"@tiptap/react": patch
+"@tiptap/vue-2": patch
+"@tiptap/vue-3": patch
+---
+
+fix(nodeview): eliminate unnecessary re-renders, add opt-in position tracking
+
+NodeViews no longer re-render when decorations or position change without
+content changes. Added `trackNodeViewPosition` option — when enabled, the
+component re-renders on every position shift so calls to `getPos()` stay
+current in render output. Removed the internal `nodeViewPositionRegistry`.
+Added shallow prop comparison in `ReactRenderer.updateProps()`.
diff --git a/demos/src/Extensions/DragHandleWithNodeViews/React/extensions/recommendation/Recommendation.jsx b/demos/src/Extensions/DragHandleWithNodeViews/React/extensions/recommendation/Recommendation.jsx
index 16ce45807b..2b4dd24659 100644
--- a/demos/src/Extensions/DragHandleWithNodeViews/React/extensions/recommendation/Recommendation.jsx
+++ b/demos/src/Extensions/DragHandleWithNodeViews/React/extensions/recommendation/Recommendation.jsx
@@ -58,7 +58,9 @@ export const Recommendation = Node.create({
},
addNodeView() {
- return ReactNodeViewRenderer(RecommendationView)
+ return ReactNodeViewRenderer(RecommendationView, {
+ trackNodeViewPosition: true,
+ })
},
})
diff --git a/demos/src/Extensions/DragHandleWithNodeViews/Vue/extensions/recommendation/Recommendation.js b/demos/src/Extensions/DragHandleWithNodeViews/Vue/extensions/recommendation/Recommendation.js
index 77277d56d6..538e14333d 100644
--- a/demos/src/Extensions/DragHandleWithNodeViews/Vue/extensions/recommendation/Recommendation.js
+++ b/demos/src/Extensions/DragHandleWithNodeViews/Vue/extensions/recommendation/Recommendation.js
@@ -43,7 +43,9 @@ export const Recommendation = Node.create({
},
addNodeView() {
- return VueNodeViewRenderer(RecommendationView)
+ return VueNodeViewRenderer(RecommendationView, {
+ trackNodeViewPosition: true,
+ })
},
})
diff --git a/demos/src/GuideNodeViews/Decorations/React/Component.tsx b/demos/src/GuideNodeViews/Decorations/React/Component.tsx
new file mode 100644
index 0000000000..6413fe8bca
--- /dev/null
+++ b/demos/src/GuideNodeViews/Decorations/React/Component.tsx
@@ -0,0 +1,33 @@
+import type { ReactNodeViewProps } from '@tiptap/react'
+import { NodeViewContent, NodeViewWrapper } from '@tiptap/react'
+import React, { useRef } from 'react'
+
+export default (props: ReactNodeViewProps) => {
+ const renderCount = useRef(0)
+ renderCount.current += 1
+
+ const toggleHighlight = () => {
+ props.updateAttributes({
+ highlight: !props.node.attrs.highlight,
+ })
+ }
+
+ const showPosition = () => {
+ alert(`Current position: ${props.getPos()}`)
+ }
+
+ return (
+
+ React Decorations (rendered: {renderCount.current}x)
+
+
+
+
+
+ {props.node.attrs.highlight ? 'Remove Decorations' : 'Add Decorations'}
+
+ Show Position
+
+
+ )
+}
diff --git a/demos/src/GuideNodeViews/Decorations/React/Extension.ts b/demos/src/GuideNodeViews/Decorations/React/Extension.ts
new file mode 100644
index 0000000000..fce98876f4
--- /dev/null
+++ b/demos/src/GuideNodeViews/Decorations/React/Extension.ts
@@ -0,0 +1,74 @@
+import { mergeAttributes, Node } from '@tiptap/core'
+import { Plugin } from '@tiptap/pm/state'
+import { Decoration, DecorationSet } from '@tiptap/pm/view'
+import { ReactNodeViewRenderer } from '@tiptap/react'
+
+import Component from './Component.jsx'
+
+export default Node.create({
+ name: 'decorations',
+
+ group: 'block',
+
+ content: 'inline*',
+
+ addAttributes() {
+ return {
+ highlight: {
+ default: false,
+ parseHTML: element => element.getAttribute('data-highlight') === 'true',
+ renderHTML: attributes => ({
+ 'data-highlight': attributes.highlight,
+ }),
+ },
+ }
+ },
+
+ parseHTML() {
+ return [
+ {
+ tag: 'decorations',
+ },
+ ]
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return ['decorations', mergeAttributes(HTMLAttributes), 0]
+ },
+
+ addProseMirrorPlugins() {
+ return [
+ new Plugin({
+ props: {
+ decorations(state) {
+ const { doc } = state
+ const decorations: Decoration[] = []
+ const nodeType = state.schema.nodes.decorations
+
+ doc.descendants((node, pos) => {
+ if (node.type === nodeType && node.attrs.highlight) {
+ node.forEach((child, offset) => {
+ if (child.isText && child.text) {
+ const from = pos + 1 + offset
+ const to = from + child.text.length
+ decorations.push(
+ Decoration.inline(from, to, {
+ class: 'highlight-decoration',
+ }),
+ )
+ }
+ })
+ }
+ })
+
+ return DecorationSet.create(doc, decorations)
+ },
+ },
+ }),
+ ]
+ },
+
+ addNodeView() {
+ return ReactNodeViewRenderer(Component)
+ },
+})
diff --git a/demos/src/GuideNodeViews/Decorations/React/index.html b/demos/src/GuideNodeViews/Decorations/React/index.html
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/demos/src/GuideNodeViews/Decorations/React/index.tsx b/demos/src/GuideNodeViews/Decorations/React/index.tsx
new file mode 100644
index 0000000000..aa80755fdd
--- /dev/null
+++ b/demos/src/GuideNodeViews/Decorations/React/index.tsx
@@ -0,0 +1,28 @@
+import './styles.scss'
+
+import { EditorContent, useEditor } from '@tiptap/react'
+import StarterKit from '@tiptap/starter-kit'
+import React from 'react'
+
+import DecorationsExtension from './Extension.js'
+
+export default () => {
+ const editor = useEditor({
+ extensions: [StarterKit, DecorationsExtension],
+ content: `
+
+ This demo shows that ProseMirror decorations update visually without React re-renders.
+
+
+ Click the button below to toggle decorations. The render counter in the label
+ stays the same — but the decorations (highlights) update immediately.
+
+
+ ProseMirror manages the contentDOM natively. The React component only
+ re-renders when the node reference or position actually changes.
+
+ `,
+ })
+
+ return
+}
diff --git a/demos/src/GuideNodeViews/Decorations/React/styles.scss b/demos/src/GuideNodeViews/Decorations/React/styles.scss
new file mode 100644
index 0000000000..a04b1527ed
--- /dev/null
+++ b/demos/src/GuideNodeViews/Decorations/React/styles.scss
@@ -0,0 +1,147 @@
+/* Basic editor styles */
+.tiptap {
+ :first-child {
+ margin-top: 0;
+ }
+
+ ul,
+ ol {
+ padding: 0 1rem;
+ margin: 1.25rem 1rem 1.25rem 0.4rem;
+
+ li p {
+ margin-top: 0.25em;
+ margin-bottom: 0.25em;
+ }
+ }
+
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6 {
+ line-height: 1.1;
+ margin-top: 2.5rem;
+ text-wrap: pretty;
+ }
+
+ h1,
+ h2 {
+ margin-top: 3.5rem;
+ margin-bottom: 1.5rem;
+ }
+
+ h1 {
+ font-size: 1.4rem;
+ }
+
+ h2 {
+ font-size: 1.2rem;
+ }
+
+ h3 {
+ font-size: 1.1rem;
+ }
+
+ h4,
+ h5,
+ h6 {
+ font-size: 1rem;
+ }
+
+ code {
+ background-color: var(--purple-light);
+ border-radius: 0.4rem;
+ color: var(--black);
+ font-size: 0.85rem;
+ padding: 0.25em 0.3em;
+ }
+
+ pre {
+ background: var(--black);
+ border-radius: 0.5rem;
+ color: var(--white);
+ font-family: 'JetBrainsMono', monospace;
+ margin: 1.5rem 0;
+ padding: 0.75rem 1rem;
+
+ code {
+ background: none;
+ color: inherit;
+ font-size: 0.8rem;
+ padding: 0;
+ }
+ }
+
+ blockquote {
+ border-left: 3px solid var(--gray-3);
+ margin: 1.5rem 0;
+ padding-left: 1rem;
+ }
+
+ hr {
+ border: none;
+ border-top: 1px solid var(--gray-2);
+ margin: 2rem 0;
+ }
+
+ /* React component */
+ .react-component {
+ background-color: var(--purple-light);
+ border: 2px solid var(--purple);
+ border-radius: 0.5rem;
+ margin: 2rem 0;
+ position: relative;
+
+ label {
+ background-color: var(--purple);
+ border-radius: 0 0 0.5rem 0;
+ color: var(--white);
+ font-size: 0.75rem;
+ font-weight: bold;
+ padding: 0.25rem 0.5rem;
+ position: absolute;
+ top: 0;
+ }
+
+ .content {
+ margin-top: 1.5rem;
+ padding: 1rem;
+
+ &.is-editable {
+ border: 2px dashed var(--gray-3);
+ border-radius: 0.5rem;
+ margin: 2.5rem 1rem 1rem;
+ padding: 0.5rem;
+ }
+ }
+
+ .toolbar {
+ padding: 0 1rem 1rem;
+ display: flex;
+ gap: 0.5rem;
+
+ button {
+ background-color: var(--purple);
+ border: none;
+ border-radius: 0.25rem;
+ color: var(--white);
+ cursor: pointer;
+ font-size: 0.85rem;
+ padding: 0.5rem 1rem;
+
+ &:hover {
+ opacity: 0.8;
+ }
+ }
+ }
+ }
+
+ /* Decoration styles — rendered by ProseMirror, not React */
+ .highlight-decoration {
+ background-color: rgba(255, 230, 0, 0.4);
+ border-radius: 0.15rem;
+ padding: 0.1rem 0;
+ }
+}
diff --git a/demos/src/GuideNodeViews/Decorations/Vue/Component.vue b/demos/src/GuideNodeViews/Decorations/Vue/Component.vue
new file mode 100644
index 0000000000..c06f68159d
--- /dev/null
+++ b/demos/src/GuideNodeViews/Decorations/Vue/Component.vue
@@ -0,0 +1,107 @@
+
+
+ Vue Decorations (rendered: {{ renderCount }}x)
+
+
+
+
+
+ {{ node.attrs.highlight ? 'Remove Decorations' : 'Add Decorations' }}
+
+ Show Position
+
+
+
+
+
+
+
diff --git a/demos/src/GuideNodeViews/Decorations/Vue/Extension.js b/demos/src/GuideNodeViews/Decorations/Vue/Extension.js
new file mode 100644
index 0000000000..c230d19e47
--- /dev/null
+++ b/demos/src/GuideNodeViews/Decorations/Vue/Extension.js
@@ -0,0 +1,74 @@
+import { mergeAttributes, Node } from '@tiptap/core'
+import { Plugin } from '@tiptap/pm/state'
+import { Decoration, DecorationSet } from '@tiptap/pm/view'
+import { VueNodeViewRenderer } from '@tiptap/vue-3'
+
+import Component from './Component.vue'
+
+export default Node.create({
+ name: 'decorations',
+
+ group: 'block',
+
+ content: 'inline*',
+
+ addAttributes() {
+ return {
+ highlight: {
+ default: false,
+ parseHTML: element => element.getAttribute('data-highlight') === 'true',
+ renderHTML: attributes => ({
+ 'data-highlight': attributes.highlight,
+ }),
+ },
+ }
+ },
+
+ parseHTML() {
+ return [
+ {
+ tag: 'decorations',
+ },
+ ]
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return ['decorations', mergeAttributes(HTMLAttributes), 0]
+ },
+
+ addProseMirrorPlugins() {
+ return [
+ new Plugin({
+ props: {
+ decorations(state) {
+ const { doc } = state
+ const decorations = []
+ const nodeType = state.schema.nodes.decorations
+
+ doc.descendants((node, pos) => {
+ if (node.type === nodeType && node.attrs.highlight) {
+ node.forEach((child, offset) => {
+ if (child.isText && child.text) {
+ const from = pos + 1 + offset
+ const to = from + child.text.length
+ decorations.push(
+ Decoration.inline(from, to, {
+ class: 'highlight-decoration',
+ }),
+ )
+ }
+ })
+ }
+ })
+
+ return DecorationSet.create(doc, decorations)
+ },
+ },
+ }),
+ ]
+ },
+
+ addNodeView() {
+ return VueNodeViewRenderer(Component)
+ },
+})
diff --git a/demos/src/GuideNodeViews/Decorations/Vue/index.html b/demos/src/GuideNodeViews/Decorations/Vue/index.html
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/demos/src/GuideNodeViews/Decorations/Vue/index.vue b/demos/src/GuideNodeViews/Decorations/Vue/index.vue
new file mode 100644
index 0000000000..8b152aafdb
--- /dev/null
+++ b/demos/src/GuideNodeViews/Decorations/Vue/index.vue
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts
index de1bd45b99..94d94f31d9 100644
--- a/packages/core/src/types.ts
+++ b/packages/core/src/types.ts
@@ -735,6 +735,15 @@ export interface NodeViewRendererOptions {
* Defaults to `false` to preserve existing behavior.
*/
selectedOnTextSelection?: boolean
+ /**
+ * When `true`, the component re-renders on every position shift so calls
+ * to `getPos()` stay current in render output.
+ * Without this option, `getPos()` is still always current for imperative
+ * use (click handlers, commands) — it only becomes stale when directly
+ * rendered in JSX or used in reactive template expressions.
+ * @default false
+ */
+ trackNodeViewPosition?: boolean
}
export interface NodeViewRendererProps {
diff --git a/packages/core/src/utilities/index.ts b/packages/core/src/utilities/index.ts
index 2ceee61c1b..b7af44900f 100644
--- a/packages/core/src/utilities/index.ts
+++ b/packages/core/src/utilities/index.ts
@@ -24,6 +24,5 @@ export * as markdown from './markdown/index.js'
export * from './mergeAttributes.js'
export * from './mergeDeep.js'
export * from './minMax.js'
-export * from './nodeViewPositionRegistry.js'
export * from './objectIncludes.js'
export * from './removeDuplicates.js'
diff --git a/packages/core/src/utilities/nodeViewPositionRegistry.ts b/packages/core/src/utilities/nodeViewPositionRegistry.ts
deleted file mode 100644
index dfcd3d07bf..0000000000
--- a/packages/core/src/utilities/nodeViewPositionRegistry.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import type { Editor } from '../Editor.js'
-
-/**
- * Per-editor registry for centralized NodeView position-change checks.
- * A single editor.on('update') listener + rAF is shared across all NodeViews
- * for a given editor, keeping overhead bounded regardless of NodeView count.
- *
- * This is consumed by React, Vue 3, and Vue 2 NodeView renderers.
- */
-interface PositionUpdateRegistry {
- callbacks: Set<() => void>
- rafId: number | null
- handler: () => void
-}
-
-const positionUpdateRegistries = new WeakMap()
-
-/**
- * Register a callback to be called (via a shared rAF) after every editor
- * update transaction. If this is the first registration for the given editor,
- * a new registry entry and a single `editor.on('update')` listener are created.
- */
-export function schedulePositionCheck(editor: Editor, callback: () => void): void {
- let registry = positionUpdateRegistries.get(editor)
-
- if (!registry) {
- const newRegistry: PositionUpdateRegistry = {
- callbacks: new Set(),
- rafId: null,
- handler: () => {
- if (newRegistry.rafId !== null) {
- cancelAnimationFrame(newRegistry.rafId)
- }
- newRegistry.rafId = requestAnimationFrame(() => {
- newRegistry.rafId = null
- newRegistry.callbacks.forEach(cb => cb())
- })
- },
- }
-
- positionUpdateRegistries.set(editor, newRegistry)
- editor.on('update', newRegistry.handler)
- registry = newRegistry
- }
-
- registry.callbacks.add(callback)
-}
-
-/**
- * Unregister a previously registered callback. When the last callback for an
- * editor is removed, the shared listener and any pending rAF are also cleaned up.
- */
-export function cancelPositionCheck(editor: Editor, callback: () => void): void {
- const registry = positionUpdateRegistries.get(editor)
-
- if (!registry) {
- return
- }
-
- registry.callbacks.delete(callback)
-
- if (registry.callbacks.size === 0) {
- if (registry.rafId !== null) {
- cancelAnimationFrame(registry.rafId)
- }
-
- editor.off('update', registry.handler)
- positionUpdateRegistries.delete(editor)
- }
-}
diff --git a/packages/react/src/ReactNodeViewRenderer.tsx b/packages/react/src/ReactNodeViewRenderer.tsx
index a796d82cca..23ab773675 100644
--- a/packages/react/src/ReactNodeViewRenderer.tsx
+++ b/packages/react/src/ReactNodeViewRenderer.tsx
@@ -5,13 +5,7 @@ import type {
NodeViewRendererOptions,
NodeViewRendererProps,
} from '@tiptap/core'
-import {
- cancelPositionCheck,
- getRenderedAttributes,
- isNodeViewSelected,
- NodeView,
- schedulePositionCheck,
-} from '@tiptap/core'
+import { getRenderedAttributes, isNodeViewSelected, NodeView } from '@tiptap/core'
import type { Node, Node as ProseMirrorNode } from '@tiptap/pm/model'
import type { Decoration, DecorationSource, NodeView as ProseMirrorNodeView } from '@tiptap/pm/view'
import type { ComponentType, NamedExoticComponent } from 'react'
@@ -85,10 +79,21 @@ export class ReactNodeView<
private currentPos: number | undefined
/**
- * Callback registered with the per-editor position-update registry.
- * Stored so it can be unregistered in destroy().
+ * Fires on editor updates when trackNodeViewPosition is enabled.
+ * Detects position shifts where update() is NOT called (e.g. typing above).
*/
- private positionCheckCallback: (() => void) | null = null
+ private handlePositionUpdate = () => {
+ const newPos = this.getPos()
+ if (typeof newPos !== 'number' || newPos === this.currentPos) {
+ return
+ }
+ this.currentPos = newPos
+ this.renderer.updateProps({ getPos: () => this.getPos() })
+
+ if (typeof this.options.attrs === 'function') {
+ this.updateElementAttributes()
+ }
+ }
constructor(component: Component, props: NodeViewRendererProps, options?: Partial) {
super(component, props, options)
@@ -116,6 +121,10 @@ export class ReactNodeView<
contentTarget.appendChild(this.contentDOMElement)
}
+
+ if (this.options.trackNodeViewPosition) {
+ this.editor.on('update', this.handlePositionUpdate)
+ }
}
private cachedExtensionWithSyncedStorage: NodeViewRendererProps['extension'] | null = null
@@ -148,7 +157,7 @@ export class ReactNodeView<
* Called on initialization.
*/
mount() {
- const props = {
+ const props: Record = {
editor: this.editor,
node: this.node,
decorations: this.decorations as DecorationWithType[],
@@ -161,7 +170,9 @@ export class ReactNodeView<
updateAttributes: (attributes = {}) => this.updateAttributes(attributes),
deleteNode: () => this.deleteNode(),
ref: createRef(),
- } satisfies ReactNodeViewProps
+ }
+
+ const mountProps = props as ReactNodeViewProps
if (!(this.component as any).displayName) {
const capitalizeFirstChar = (string: string): string => {
@@ -207,7 +218,7 @@ export class ReactNodeView<
this.renderer = new ReactRenderer(ReactNodeViewProvider, {
editor: this.editor,
- props,
+ props: mountProps,
as,
className: `node-${this.node.type.name} ${className}`.trim(),
})
@@ -215,25 +226,6 @@ export class ReactNodeView<
this.editor.on('selectionUpdate', this.handleSelectionUpdate)
this.updateElementAttributes()
this.currentPos = this.getPos()
-
- this.positionCheckCallback = () => {
- const newPos = this.getPos()
-
- if (typeof newPos !== 'number' || newPos === this.currentPos) {
- return
- }
-
- this.currentPos = newPos
-
- // Pass a fresh getPos reference so React's memo detects a prop change.
- this.renderer.updateProps({ getPos: () => this.getPos() })
-
- if (typeof this.options.attrs === 'function') {
- this.updateElementAttributes()
- }
- }
-
- schedulePositionCheck(this.editor, this.positionCheckCallback)
}
/**
@@ -342,34 +334,41 @@ export class ReactNodeView<
})
}
- const newPos = this.getPos()
+ const nodeChanged = node !== this.node
- if (node === this.node && this.decorations === decorations && this.innerDecorations === innerDecorations) {
- if (newPos === this.currentPos) {
- return true
- }
-
- // Position changed without a content/decoration change — trigger re-render
- // so the component receives an up-to-date value from getPos().
- // Pass a fresh getPos reference so React's memo detects a prop change.
- this.currentPos = newPos
- rerenderComponent({
- node,
- decorations,
- innerDecorations,
- extension: this.extensionWithSyncedStorage,
- getPos: () => this.getPos(),
- })
+ // Node reference unchanged — only decorations may have changed.
+ // ProseMirror renders decorations independently on the contentDOM,
+ // and the getPos closure (bound in mount()) calls through to
+ // ProseMirror's position function at call time, so it is always
+ // current. Update internal refs and skip the React re-render.
+ // Keep currentPos unchanged here so the editor update listener can
+ // still detect and publish a position shift for tracked node views.
+ if (!nodeChanged) {
+ this.node = node
+ this.decorations = decorations
+ this.innerDecorations = innerDecorations
return true
}
+ const newPos = this.getPos()
+
this.node = node
this.decorations = decorations
this.innerDecorations = innerDecorations
this.currentPos = newPos
- rerenderComponent({ node, decorations, innerDecorations, extension: this.extensionWithSyncedStorage })
+ const extraProps: Record = {
+ node,
+ decorations,
+ innerDecorations,
+ extension: this.extensionWithSyncedStorage,
+ }
+
+ if (this.options.trackNodeViewPosition) {
+ extraProps.getPos = () => this.getPos()
+ }
+ rerenderComponent(extraProps)
return true
}
@@ -402,9 +401,8 @@ export class ReactNodeView<
this.renderer.destroy()
this.editor.off('selectionUpdate', this.handleSelectionUpdate)
- if (this.positionCheckCallback) {
- cancelPositionCheck(this.editor, this.positionCheckCallback)
- this.positionCheckCallback = null
+ if (this.options.trackNodeViewPosition) {
+ this.editor.off('update', this.handlePositionUpdate)
}
this.contentDOMElement = null
diff --git a/packages/react/src/ReactRenderer.tsx b/packages/react/src/ReactRenderer.tsx
index 7ed5eee850..299c782c3e 100644
--- a/packages/react/src/ReactRenderer.tsx
+++ b/packages/react/src/ReactRenderer.tsx
@@ -236,12 +236,30 @@ export class ReactRenderer = object>
/**
* Re-renders the React component with new props.
+ * Skips the render if none of the supplied props actually changed,
+ * to avoid unnecessary portal re-creation.
*/
updateProps(props: Record = {}): void {
if (this.destroyed) {
return
}
+ // Shallow comparison — skip if every supplied key already holds the same value.
+ let changed = false
+ const keys = Object.keys(props)
+
+ for (let i = 0; i < keys.length; i += 1) {
+ const key = keys[i]
+ if (props[key] !== this.props[key]) {
+ changed = true
+ break
+ }
+ }
+
+ if (!changed) {
+ return
+ }
+
this.props = {
...this.props,
...props,
diff --git a/packages/vue-2/src/VueNodeViewRenderer.ts b/packages/vue-2/src/VueNodeViewRenderer.ts
index 1e9461b4f4..6754a67bb6 100644
--- a/packages/vue-2/src/VueNodeViewRenderer.ts
+++ b/packages/vue-2/src/VueNodeViewRenderer.ts
@@ -1,5 +1,11 @@
-import type { DecorationWithType, NodeViewProps, NodeViewRenderer, NodeViewRendererOptions } from '@tiptap/core'
-import { cancelPositionCheck, isNodeViewSelected, NodeView, schedulePositionCheck } from '@tiptap/core'
+import type {
+ DecorationWithType,
+ NodeViewProps,
+ NodeViewRenderer,
+ NodeViewRendererOptions,
+ NodeViewRendererProps,
+} from '@tiptap/core'
+import { isNodeViewSelected, NodeView } from '@tiptap/core'
import type { Node as ProseMirrorNode } from '@tiptap/pm/model'
import type { Decoration, DecorationSource, NodeView as ProseMirrorNodeView } from '@tiptap/pm/view'
import type { VueConstructor } from 'vue'
@@ -37,24 +43,35 @@ export interface VueNodeViewRendererOptions extends NodeViewRendererOptions {
class VueNodeView extends NodeView {
renderer!: VueRenderer
- /**
- * The last known position of this node view, used to detect position-only
- * changes that don't produce a new node object reference.
- */
+ decorationClasses!: {
+ value: string
+ }
+
private currentPos: number | undefined
- /**
- * Callback registered with the per-editor position-update registry.
- * Stored so it can be unregistered in destroy().
- */
- private positionCheckCallback: (() => void) | null = null
+ constructor(
+ component: Vue | VueConstructor,
+ props: NodeViewRendererProps,
+ options?: Partial,
+ ) {
+ super(component, props, options)
- decorationClasses!: {
- value: string
+ if (this.options.trackNodeViewPosition) {
+ this.editor.on('update', this.handlePositionUpdate)
+ }
+ }
+
+ private handlePositionUpdate = () => {
+ const newPos = this.getPos()
+ if (typeof newPos !== 'number' || newPos === this.currentPos) {
+ return
+ }
+ this.currentPos = newPos
+ this.renderer.updateProps({ getPos: () => this.getPos() })
}
mount() {
- const props = {
+ const props: Record = {
editor: this.editor,
node: this.node,
decorations: this.decorations as DecorationWithType[],
@@ -66,7 +83,9 @@ class VueNodeView extends NodeView this.getPos(),
updateAttributes: (attributes = {}) => this.updateAttributes(attributes),
deleteNode: () => this.deleteNode(),
- } satisfies NodeViewProps
+ }
+
+ const mountProps = props as NodeViewProps
const onDragStart = this.onDragStart.bind(this)
@@ -89,31 +108,12 @@ class VueNodeView extends NodeView {
- // Guard against the callback firing before the renderer is fully initialized.
- if (!this.renderer) {
- return
- }
-
- const newPos = this.getPos()
-
- if (typeof newPos !== 'number' || newPos === this.currentPos) {
- return
- }
-
- this.currentPos = newPos
- // Pass a fresh getPos reference so Vue's reactivity detects a prop change.
- this.renderer.updateProps({ getPos: () => this.getPos() })
- }
-
- schedulePositionCheck(this.editor, this.positionCheckCallback)
+ this.currentPos = this.getPos()
this.renderer = new VueRenderer(Component, {
parent: this.editor.contentComponent,
- propsData: props,
+ propsData: mountProps,
})
}
@@ -192,7 +192,6 @@ class VueNodeView extends NodeView this.getPos() })
+ // Node reference unchanged — only decorations may have changed.
+ // ProseMirror renders decorations independently on the contentDOM,
+ // and the getPos closure (bound in mount()) calls through to
+ // ProseMirror's position function at call time, so it is always
+ // current. Update internal refs, refresh decoration classes for
+ // the wrapper component, and skip the Vue re-render.
+ if (!nodeChanged) {
+ this.node = node
+ this.decorations = decorations
+ this.innerDecorations = innerDecorations
+ this.decorationClasses.value = this.getDecorationClasses()
return true
}
this.node = node
this.decorations = decorations
this.innerDecorations = innerDecorations
- this.currentPos = newPos
+ this.currentPos = this.getPos()
+
+ const extraProps: Record = {
+ node,
+ decorations,
+ innerDecorations,
+ }
+
+ if (this.options.trackNodeViewPosition) {
+ extraProps.getPos = () => this.getPos()
+ }
- rerenderComponent({ node, decorations, innerDecorations })
+ rerenderComponent(extraProps)
return true
}
@@ -269,9 +279,8 @@ class VueNodeView extends NodeView
- /**
- * The last known position of this node view, used to detect position-only
- * changes that don't produce a new node object reference.
- */
private currentPos: number | undefined
- /**
- * Callback registered with the per-editor position-update registry.
- * Stored so it can be unregistered in destroy().
- */
- private positionCheckCallback: (() => void) | null = null
-
private cachedExtensionWithSyncedStorage: NodeViewProps['extension'] | null = null
+ constructor(component: Component, props: NodeViewRendererProps, options?: Partial) {
+ super(component, props, options)
+
+ if (this.options.trackNodeViewPosition) {
+ this.editor.on('update', this.handlePositionUpdate)
+ }
+ }
+
/**
* Returns a proxy of the extension that redirects storage access to the editor's mutable storage.
* This preserves the original prototype chain (instanceof checks, methods like configure/extend work).
@@ -113,7 +117,7 @@ class VueNodeView extends NodeView = {
editor: this.editor,
node: this.node,
decorations: this.decorations as DecorationWithType[],
@@ -125,7 +129,9 @@ class VueNodeView extends NodeView this.getPos(),
updateAttributes: (attributes = {}) => this.updateAttributes(attributes),
deleteNode: () => this.deleteNode(),
- } satisfies NodeViewProps
+ }
+
+ const mountProps = props as NodeViewProps
const onDragStart = this.onDragStart.bind(this)
@@ -162,34 +168,28 @@ class VueNodeView extends NodeView {
- // Guard against the callback firing before the renderer is fully initialized.
- if (!this.renderer) {
- return
- }
-
- const newPos = this.getPos()
-
- if (typeof newPos !== 'number' || newPos === this.currentPos) {
- return
- }
-
- this.currentPos = newPos
-
- // Pass a fresh getPos reference so Vue's reactivity detects a prop change.
- this.renderer.updateProps({ getPos: () => this.getPos() })
- }
-
- schedulePositionCheck(this.editor, this.positionCheckCallback)
+ this.currentPos = this.getPos()
this.renderer = new VueRenderer(extendedComponent, {
editor: this.editor,
- props,
+ props: mountProps,
})
}
+ /**
+ * Fires on editor updates when trackNodeViewPosition is enabled.
+ * Detects position shifts where update() is NOT called.
+ */
+ private handlePositionUpdate = () => {
+ const newPos = this.getPos()
+ if (typeof newPos !== 'number' || newPos === this.currentPos) {
+ return
+ }
+ this.currentPos = newPos
+ this.renderer.updateProps({ getPos: () => this.getPos() })
+ }
+
/**
* Return the DOM element.
* This is the element that will be used to display the node view.
@@ -265,7 +265,6 @@ class VueNodeView extends NodeView this.getPos(),
- })
+ // Node reference unchanged — only decorations may have changed.
+ // ProseMirror renders decorations independently on the contentDOM,
+ // and the getPos closure (bound in mount()) calls through to
+ // ProseMirror's position function at call time, so it is always
+ // current. Update internal refs, refresh decoration classes for
+ // the wrapper component, and skip the Vue re-render.
+ if (!nodeChanged) {
+ this.node = node
+ this.decorations = decorations
+ this.innerDecorations = innerDecorations
+ this.decorationClasses.value = this.getDecorationClasses()
return true
}
this.node = node
this.decorations = decorations
this.innerDecorations = innerDecorations
- this.currentPos = newPos
+ this.currentPos = this.getPos()
- rerenderComponent({ node, decorations, innerDecorations, extension: this.extensionWithSyncedStorage })
+ const extraProps: Record = {
+ node,
+ decorations,
+ innerDecorations,
+ extension: this.extensionWithSyncedStorage,
+ }
+
+ if (this.options.trackNodeViewPosition) {
+ extraProps.getPos = () => this.getPos()
+ }
+ rerenderComponent(extraProps)
return true
}
@@ -353,9 +357,8 @@ class VueNodeView extends NodeView
Date: Tue, 19 May 2026 12:11:00 +0200
Subject: [PATCH 3/5] Add test for inserting plain text content (#7843)
* test(core): add test for inserting plain text content
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---
packages/core/__tests__/insertContent.spec.ts | 28 +++++++++++++++++++
1 file changed, 28 insertions(+)
create mode 100644 packages/core/__tests__/insertContent.spec.ts
diff --git a/packages/core/__tests__/insertContent.spec.ts b/packages/core/__tests__/insertContent.spec.ts
new file mode 100644
index 0000000000..2511bd6d08
--- /dev/null
+++ b/packages/core/__tests__/insertContent.spec.ts
@@ -0,0 +1,28 @@
+import { Editor } from '@tiptap/core'
+import Document from '@tiptap/extension-document'
+import Paragraph from '@tiptap/extension-paragraph'
+import Text from '@tiptap/extension-text'
+import { afterEach, describe, expect, it } from 'vitest'
+
+describe('insertContent', () => {
+ let editor: Editor
+
+ afterEach(() => {
+ editor?.destroy()
+ })
+
+ it('inserts plain text object {type: "text", text: "world"}', () => {
+ editor = new Editor({
+ extensions: [Document, Paragraph, Text],
+ content: 'hello
',
+ })
+
+ // Place cursor at the end of "hello" (position 6)
+ editor.commands.setTextSelection(6)
+
+ const result = editor.commands.insertContent({ type: 'text', text: 'world' })
+
+ expect(result).toBe(true)
+ expect(editor.getHTML()).toBe('helloworld
')
+ })
+})
From 7bf0e731f71ac794ced318a90bccdb1b105cf475 Mon Sep 17 00:00:00 2001
From: bdbch <6538827+bdbch@users.noreply.github.com>
Date: Tue, 19 May 2026 13:50:25 +0200
Subject: [PATCH 4/5] fix(markdown): serialize adjacent marks with different
attributes separately (#7844)
* fix(markdown): serialize adjacent marks with different attributes separately
* fix(markdown): address Copilot review feedback
- Fix attrsEqual to check key presence in both objects and use Object.is
- Remove duplicate JSDoc block in markSetsEqual
- Make getMarksToOpenForSerialization attr-aware for continuing/ending logic
- Hoist normalizeMarks to module level to avoid duplication
---
.changeset/silent-baboons-explain.md | 5 +
.../__tests__/overlapping-marks.spec.ts | 148 ++++++++++++++++--
packages/markdown/src/MarkdownManager.ts | 24 ++-
packages/markdown/src/utils.ts | 63 +++++++-
4 files changed, 212 insertions(+), 28 deletions(-)
create mode 100644 .changeset/silent-baboons-explain.md
diff --git a/.changeset/silent-baboons-explain.md b/.changeset/silent-baboons-explain.md
new file mode 100644
index 0000000000..f097dddc2c
--- /dev/null
+++ b/.changeset/silent-baboons-explain.md
@@ -0,0 +1,5 @@
+---
+"@tiptap/markdown": patch
+---
+
+Fix adjacent marks of the same type with different attributes being merged during Markdown serialization
diff --git a/packages/markdown/__tests__/overlapping-marks.spec.ts b/packages/markdown/__tests__/overlapping-marks.spec.ts
index a6eb17df0e..57cfb7b199 100644
--- a/packages/markdown/__tests__/overlapping-marks.spec.ts
+++ b/packages/markdown/__tests__/overlapping-marks.spec.ts
@@ -12,24 +12,30 @@ import { describe, expect, it } from 'vitest'
import { MarkdownManager } from '../src/MarkdownManager.js'
-describe('Overlapping marks serialization', () => {
- const extensions = [Document, Paragraph, Text, Bold, Italic, Link]
- const markdownManager = new MarkdownManager({ extensions })
- const normalizeMarks = (node: any): any => {
- if (Array.isArray(node)) {
- return node.map(normalizeMarks)
- }
+/**
+ * Normalize marks order for deterministic comparison. Marks in the same position
+ * can be stored in any order by ProseMirror; sorting by type ensures
+ * deep-equality assertions don't flake on array ordering.
+ */
+const normalizeMarks = (node: any): any => {
+ if (Array.isArray(node)) {
+ return node.map(normalizeMarks)
+ }
- if (!node || typeof node !== 'object') {
- return node
- }
+ if (!node || typeof node !== 'object') {
+ return node
+ }
- return {
- ...node,
- marks: node.marks ? [...node.marks].sort((a, b) => a.type.localeCompare(b.type)) : node.marks,
- content: node.content ? node.content.map(normalizeMarks) : node.content,
- }
+ return {
+ ...node,
+ marks: node.marks ? [...node.marks].sort((a: any, b: any) => a.type.localeCompare(b.type)) : node.marks,
+ content: node.content ? node.content.map(normalizeMarks) : node.content,
}
+}
+
+describe('Overlapping marks serialization', () => {
+ const extensions = [Document, Paragraph, Text, Bold, Italic, Link]
+ const markdownManager = new MarkdownManager({ extensions })
/**
* Regression test for the original bug report.
@@ -531,3 +537,115 @@ describe('Overlapping marks serialization', () => {
expect(normalizeMarks(markdownManagerWithStrike.parse(result))).toEqual(normalizeMarks(json))
})
})
+
+/**
+ * Regression tests for issue #7682.
+ *
+ * Adjacent marks of the same type (e.g. links) with different attributes must
+ * be serialized as separate marks instead of being merged into one.
+ */
+describe('adjacent marks with different attributes', () => {
+ const extensions = [Document, Paragraph, Text, Link]
+ const markdownManager = new MarkdownManager({ extensions })
+
+ it('should serialize adjacent links with different href values as separate links', () => {
+ const json = {
+ type: 'doc',
+ content: [
+ {
+ type: 'paragraph',
+ content: [
+ {
+ type: 'text',
+ text: 'example',
+ marks: [{ type: 'link', attrs: { href: 'https://example.com', title: null } }],
+ },
+ {
+ type: 'text',
+ text: 'github',
+ marks: [{ type: 'link', attrs: { href: 'https://github.com', title: null } }],
+ },
+ {
+ type: 'text',
+ text: 'tiptap',
+ marks: [{ type: 'link', attrs: { href: 'https://tiptap.dev', title: null } }],
+ },
+ ],
+ },
+ ],
+ }
+
+ const result = markdownManager.serialize(json)
+
+ // Each adjacent link must be rendered with its own URL — not merged into one
+ expect(result).toBe('[example](https://example.com)[github](https://github.com)[tiptap](https://tiptap.dev)')
+ // Verify round-trip fidelity
+ expect(normalizeMarks(markdownManager.parse(result))).toEqual(normalizeMarks(json))
+ })
+
+ it('should keep links with the same href and attributes merged', () => {
+ const json = {
+ type: 'doc',
+ content: [
+ {
+ type: 'paragraph',
+ content: [
+ {
+ type: 'text',
+ text: 'the same',
+ marks: [{ type: 'link', attrs: { href: 'https://example.com', title: null } }],
+ },
+ {
+ type: 'text',
+ text: ' link',
+ marks: [{ type: 'link', attrs: { href: 'https://example.com', title: null } }],
+ },
+ ],
+ },
+ ],
+ }
+
+ const result = markdownManager.serialize(json)
+
+ // Links with the same href and attributes are merged into one
+ expect(result).toBe('[the same link](https://example.com)')
+
+ // Verify re-serialization stability: parse then re-serialize produces the same output
+ const parsed = markdownManager.parse(result)
+ expect(markdownManager.serialize(parsed)).toBe(result)
+ })
+
+ it('should handle adjacent links with titles alongside links without titles', () => {
+ const json = {
+ type: 'doc',
+ content: [
+ {
+ type: 'paragraph',
+ content: [
+ {
+ type: 'text',
+ text: 'with title',
+ marks: [{ type: 'link', attrs: { href: 'https://example.com', title: 'Example' } }],
+ },
+ {
+ type: 'text',
+ text: ' no title',
+ marks: [{ type: 'link', attrs: { href: 'https://example.org', title: null } }],
+ },
+ ],
+ },
+ ],
+ }
+
+ const result = markdownManager.serialize(json)
+
+ // Note: the leading space in " no title" is extracted outside the link
+ // brackets by the serializer's whitespace handling, resulting in a space
+ // between the two link markdown fragments.
+ expect(result).toBe('[with title](https://example.com "Example") [no title](https://example.org)')
+
+ // Verify re-serialization stability: parse then re-serialize produces the same output
+ const parsed = markdownManager.parse(result)
+ expect(markdownManager.serialize(parsed)).toBe(result)
+ })
+})
diff --git a/packages/markdown/src/MarkdownManager.ts b/packages/markdown/src/MarkdownManager.ts
index 17edc5d14c..0dc4c47acd 100644
--- a/packages/markdown/src/MarkdownManager.ts
+++ b/packages/markdown/src/MarkdownManager.ts
@@ -21,6 +21,7 @@ import {
import { type Lexer, type Token, type TokenizerExtension, type TokenizerThis, marked } from 'marked'
import {
+ attrsEqual,
closeMarksBeforeNode,
findMarksToClose,
findMarksToCloseAtEnd,
@@ -1324,14 +1325,17 @@ export class MarkdownManager {
}
/**
- * Check if two mark sets are equal.
+ * Check if two mark sets are equal (same types and matching attributes).
*/
private markSetsEqual(marks1: Map, marks2: Map): boolean {
if (marks1.size !== marks2.size) {
return false
}
- return Array.from(marks1.keys()).every(type => marks2.has(type))
+ return Array.from(marks1.entries()).every(([type, mark]) => {
+ const otherMark = marks2.get(type)
+ return otherMark && attrsEqual(mark.attrs, otherMark.attrs)
+ })
}
/**
@@ -1359,7 +1363,13 @@ export class MarkdownManager {
return marksToOpen
}
- const nextMarkTypes = new Set((nextNode?.marks || []).map((mark: any) => mark.type))
+ const nextMarks = nextNode?.marks || []
+
+ // Helper: check if the next node has a mark with the same type AND
+ // matching attributes. Two marks of the same type but with different
+ // attributes are logically distinct and must not be treated as continuing.
+ const continuesInNextNode = (markType: string, attrs: any) =>
+ nextMarks.some((m: any) => m.type === markType && attrsEqual(m.attrs, attrs))
// Higher rank → earlier in the array → innermost mark. Marks without a
// recorded rank fall back to MAX_SAFE_INTEGER so they sort innermost,
@@ -1375,8 +1385,12 @@ export class MarkdownManager {
return a.type.localeCompare(b.type)
}
- const endingHere = marksToOpen.filter(mark => !nextMarkTypes.has(mark.type)).sort(byRankInnerFirst)
- const continuing = marksToOpen.filter(mark => nextMarkTypes.has(mark.type)).sort(byRankInnerFirst)
+ const endingHere = marksToOpen
+ .filter(mark => !continuesInNextNode(mark.type, mark.mark.attrs))
+ .sort(byRankInnerFirst)
+ const continuing = marksToOpen
+ .filter(mark => continuesInNextNode(mark.type, mark.mark.attrs))
+ .sort(byRankInnerFirst)
return [...endingHere, ...continuing]
}
diff --git a/packages/markdown/src/utils.ts b/packages/markdown/src/utils.ts
index 1f3bf7a13f..0524586dd6 100644
--- a/packages/markdown/src/utils.ts
+++ b/packages/markdown/src/utils.ts
@@ -24,14 +24,52 @@ export function wrapInMarkdownBlock(prefix: string, content: string) {
return output.slice(0, output.length - 1)
}
+/**
+ * Compare two attribute objects for equality.
+ * Handles null/undefined and asserts key presence in both objects so that
+ * `{ foo: undefined }` and `{ bar: undefined }` are not treated as equal.
+ */
+export function attrsEqual(
+ a: Record | null | undefined,
+ b: Record | null | undefined,
+): boolean {
+ if (a === b) {
+ return true
+ }
+ if (!a || !b) {
+ return false
+ }
+
+ const keysA = Object.keys(a)
+ const keysB = Object.keys(b)
+
+ if (keysA.length !== keysB.length) {
+ return false
+ }
+
+ return keysA.every(key => Object.prototype.hasOwnProperty.call(b, key) && Object.is(a[key], b[key]))
+}
+
/**
* Identifies marks that need to be closed, based on the marks in the next node.
+ * Compares both mark type and attributes — two marks of the same type with
+ * different attributes are treated as distinct and need to be closed/reopened.
*/
export function findMarksToClose(currentMarks: Map, nextNode: any): string[] {
const marksToClose: string[] = []
- Array.from(currentMarks.keys()).forEach(markType => {
- if (!nextNode || !nextNode.marks || !nextNode.marks.map((mark: any) => mark.type).includes(markType)) {
+ Array.from(currentMarks.entries()).forEach(([markType, currentMark]) => {
+ if (!nextNode) {
+ marksToClose.push(markType)
+ return
+ }
+
+ // Check if the next node has a mark of the same type with matching attributes
+ const nextMark = (nextNode.marks || []).find(
+ (mark: any) => mark.type === markType && attrsEqual(mark.attrs, currentMark.attrs),
+ )
+
+ if (!nextMark) {
marksToClose.push(markType)
}
})
@@ -39,7 +77,10 @@ export function findMarksToClose(currentMarks: Map, nextNode: any):
}
/**
- * Identifies marks that need to be opened (in current node but not active).
+ * Identifies marks that need to be opened (in current node but not active, or
+ * active with different attributes). Two marks of the same type with different
+ * attributes are treated as distinct — the old one must be closed and the new
+ * one reopened.
*/
export function findMarksToOpen(
activeMarks: Map,
@@ -47,7 +88,10 @@ export function findMarksToOpen(
): Array<{ type: string; mark: any }> {
const marksToOpen: Array<{ type: string; mark: any }> = []
Array.from(currentMarks.entries()).forEach(([markType, mark]) => {
- if (!activeMarks.has(markType)) {
+ const activeMark = activeMarks.get(markType)
+
+ // Open if the mark type is not active, or if the attributes differ
+ if (!activeMark || !attrsEqual(activeMark.attrs, mark.attrs)) {
marksToOpen.push({ type: markType, mark })
}
})
@@ -58,6 +102,8 @@ export function findMarksToOpen(
* Determines which marks need to be closed at the end of the current text node.
* This handles cases where marks end at node boundaries or when transitioning
* to nodes with different mark sets.
+ * Compares both mark type and attributes — two marks of the same type with
+ * different attributes are treated as distinct and trigger a close/reopen.
*/
export function findMarksToCloseAtEnd(
activeMarks: Map,
@@ -75,11 +121,12 @@ export function findMarksToCloseAtEnd(
const marksToCloseAtEnd: string[] = []
if (isLastNode || nextNodeHasNoMarks || nextNodeHasDifferentMarks) {
if (nextNode && nextNode.marks) {
- const nextMarks = new Map(nextNode.marks.map((mark: any) => [mark.type, mark]))
- Array.from(activeMarks.keys())
+ Array.from(activeMarks.entries())
.reverse()
- .forEach(markType => {
- if (!nextMarks.has(markType)) {
+ .forEach(([markType, activeMark]) => {
+ // Check if nextNode has a mark of the same type with matching attrs
+ const nextMark = nextNode.marks.find((m: any) => m.type === markType && attrsEqual(m.attrs, activeMark.attrs))
+ if (!nextMark) {
marksToCloseAtEnd.push(markType)
}
})
From d9daae031a4f72ae81af039a721df66f5c0c2696 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Tue, 19 May 2026 14:46:13 +0200
Subject: [PATCH 5/5] chore(release): publish a new stable version (#7835)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
---
.changeset/chilly-lamps-applaud.md | 5 -
.changeset/fix-pos-non-text-nodes.md | 6 -
...eact-respect-immediately-render-on-next.md | 5 -
.changeset/hip-penguins-juggle.md | 14 -
.changeset/silent-baboons-explain.md | 5 -
.changeset/wet-poets-knock.md | 5 -
CHANGELOG.md | 632 ++++++++++++++++++
.../extension-character-count/CHANGELOG.md | 6 +
.../extension-character-count/package.json | 2 +-
.../extension-dropcursor/CHANGELOG.md | 6 +
.../extension-dropcursor/package.json | 2 +-
.../extension-focus/CHANGELOG.md | 6 +
.../extension-focus/package.json | 2 +-
.../extension-gapcursor/CHANGELOG.md | 6 +
.../extension-gapcursor/package.json | 2 +-
.../extension-history/CHANGELOG.md | 6 +
.../extension-history/package.json | 2 +-
.../extension-list-item/CHANGELOG.md | 6 +
.../extension-list-item/package.json | 2 +-
.../extension-list-keymap/CHANGELOG.md | 6 +
.../extension-list-keymap/package.json | 2 +-
.../extension-placeholder/CHANGELOG.md | 6 +
.../extension-placeholder/package.json | 2 +-
.../extension-table-cell/CHANGELOG.md | 6 +
.../extension-table-cell/package.json | 2 +-
.../extension-table-header/CHANGELOG.md | 6 +
.../extension-table-header/package.json | 2 +-
.../extension-table-row/CHANGELOG.md | 6 +
.../extension-table-row/package.json | 2 +-
.../extension-task-item/CHANGELOG.md | 6 +
.../extension-task-item/package.json | 2 +-
.../extension-task-list/CHANGELOG.md | 6 +
.../extension-task-list/package.json | 2 +-
packages/core/CHANGELOG.md | 15 +
packages/core/package.json | 2 +-
packages/extension-audio/CHANGELOG.md | 8 +
packages/extension-audio/package.json | 2 +-
packages/extension-blockquote/CHANGELOG.md | 8 +
packages/extension-blockquote/package.json | 2 +-
packages/extension-bold/CHANGELOG.md | 8 +
packages/extension-bold/package.json | 2 +-
packages/extension-bubble-menu/CHANGELOG.md | 9 +
packages/extension-bubble-menu/package.json | 2 +-
packages/extension-bullet-list/CHANGELOG.md | 6 +
packages/extension-bullet-list/package.json | 2 +-
.../CHANGELOG.md | 10 +
.../package.json | 2 +-
packages/extension-code-block/CHANGELOG.md | 9 +
packages/extension-code-block/package.json | 2 +-
packages/extension-code/CHANGELOG.md | 8 +
packages/extension-code/package.json | 2 +-
.../CHANGELOG.md | 9 +
.../package.json | 2 +-
packages/extension-collaboration/CHANGELOG.md | 9 +
packages/extension-collaboration/package.json | 2 +-
packages/extension-color/CHANGELOG.md | 6 +
packages/extension-color/package.json | 2 +-
packages/extension-details/CHANGELOG.md | 10 +
packages/extension-details/package.json | 2 +-
packages/extension-document/CHANGELOG.md | 8 +
packages/extension-document/package.json | 2 +-
.../extension-drag-handle-react/CHANGELOG.md | 11 +
.../extension-drag-handle-react/package.json | 2 +-
.../extension-drag-handle-vue-2/CHANGELOG.md | 9 +
.../extension-drag-handle-vue-2/package.json | 2 +-
.../extension-drag-handle-vue-3/CHANGELOG.md | 9 +
.../extension-drag-handle-vue-3/package.json | 2 +-
packages/extension-drag-handle/CHANGELOG.md | 11 +
packages/extension-drag-handle/package.json | 2 +-
packages/extension-emoji/CHANGELOG.md | 10 +
packages/extension-emoji/package.json | 2 +-
packages/extension-file-handler/CHANGELOG.md | 10 +
packages/extension-file-handler/package.json | 2 +-
packages/extension-floating-menu/CHANGELOG.md | 9 +
packages/extension-floating-menu/package.json | 2 +-
packages/extension-font-family/CHANGELOG.md | 6 +
packages/extension-font-family/package.json | 2 +-
packages/extension-hard-break/CHANGELOG.md | 8 +
packages/extension-hard-break/package.json | 2 +-
packages/extension-heading/CHANGELOG.md | 8 +
packages/extension-heading/package.json | 2 +-
packages/extension-highlight/CHANGELOG.md | 8 +
packages/extension-highlight/package.json | 2 +-
.../extension-horizontal-rule/CHANGELOG.md | 9 +
.../extension-horizontal-rule/package.json | 2 +-
packages/extension-image/CHANGELOG.md | 8 +
packages/extension-image/package.json | 2 +-
.../CHANGELOG.md | 10 +
.../package.json | 2 +-
packages/extension-italic/CHANGELOG.md | 8 +
packages/extension-italic/package.json | 2 +-
packages/extension-link/CHANGELOG.md | 9 +
packages/extension-link/package.json | 2 +-
packages/extension-list/CHANGELOG.md | 9 +
packages/extension-list/package.json | 2 +-
packages/extension-mathematics/CHANGELOG.md | 9 +
packages/extension-mathematics/package.json | 2 +-
packages/extension-mention/CHANGELOG.md | 10 +
packages/extension-mention/package.json | 2 +-
packages/extension-node-range/CHANGELOG.md | 9 +
packages/extension-node-range/package.json | 2 +-
packages/extension-ordered-list/CHANGELOG.md | 6 +
packages/extension-ordered-list/package.json | 2 +-
packages/extension-paragraph/CHANGELOG.md | 8 +
packages/extension-paragraph/package.json | 2 +-
packages/extension-strike/CHANGELOG.md | 8 +
packages/extension-strike/package.json | 2 +-
packages/extension-subscript/CHANGELOG.md | 9 +
packages/extension-subscript/package.json | 2 +-
packages/extension-superscript/CHANGELOG.md | 9 +
packages/extension-superscript/package.json | 2 +-
.../extension-table-of-contents/CHANGELOG.md | 9 +
.../extension-table-of-contents/package.json | 2 +-
packages/extension-table/CHANGELOG.md | 9 +
packages/extension-table/package.json | 2 +-
packages/extension-text-align/CHANGELOG.md | 8 +
packages/extension-text-align/package.json | 2 +-
packages/extension-text-style/CHANGELOG.md | 8 +
packages/extension-text-style/package.json | 2 +-
packages/extension-text/CHANGELOG.md | 8 +
packages/extension-text/package.json | 2 +-
packages/extension-twitch/CHANGELOG.md | 8 +
packages/extension-twitch/package.json | 2 +-
packages/extension-typography/CHANGELOG.md | 8 +
packages/extension-typography/package.json | 2 +-
packages/extension-underline/CHANGELOG.md | 8 +
packages/extension-underline/package.json | 2 +-
packages/extension-unique-id/CHANGELOG.md | 9 +
packages/extension-unique-id/package.json | 2 +-
packages/extension-youtube/CHANGELOG.md | 8 +
packages/extension-youtube/package.json | 2 +-
packages/extensions/CHANGELOG.md | 9 +
packages/extensions/package.json | 2 +-
packages/html/CHANGELOG.md | 9 +
packages/html/package.json | 2 +-
packages/markdown/CHANGELOG.md | 11 +
packages/markdown/package.json | 2 +-
packages/pm/CHANGELOG.md | 2 +
packages/pm/package.json | 2 +-
packages/react/CHANGELOG.md | 18 +
packages/react/package.json | 2 +-
packages/starter-kit/CHANGELOG.md | 31 +
packages/starter-kit/package.json | 2 +-
packages/static-renderer/CHANGELOG.md | 9 +
packages/static-renderer/package.json | 2 +-
packages/suggestion/CHANGELOG.md | 9 +
packages/suggestion/package.json | 2 +-
packages/vue-2/CHANGELOG.md | 17 +
packages/vue-2/package.json | 2 +-
packages/vue-3/CHANGELOG.md | 17 +
packages/vue-3/package.json | 2 +-
151 files changed, 1340 insertions(+), 112 deletions(-)
delete mode 100644 .changeset/chilly-lamps-applaud.md
delete mode 100644 .changeset/fix-pos-non-text-nodes.md
delete mode 100644 .changeset/fix-react-respect-immediately-render-on-next.md
delete mode 100644 .changeset/hip-penguins-juggle.md
delete mode 100644 .changeset/silent-baboons-explain.md
delete mode 100644 .changeset/wet-poets-knock.md
diff --git a/.changeset/chilly-lamps-applaud.md b/.changeset/chilly-lamps-applaud.md
deleted file mode 100644
index aacfcdcc33..0000000000
--- a/.changeset/chilly-lamps-applaud.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@tiptap/markdown": patch
----
-
-Fix extra mark tokens after inline atom nodes during Markdown serialization
diff --git a/.changeset/fix-pos-non-text-nodes.md b/.changeset/fix-pos-non-text-nodes.md
deleted file mode 100644
index 2ec21427e2..0000000000
--- a/.changeset/fix-pos-non-text-nodes.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-"@tiptap/core": patch
----
-
-Fix $pos() returning correct node for non-text atom nodes instead of doc node
-
diff --git a/.changeset/fix-react-respect-immediately-render-on-next.md b/.changeset/fix-react-respect-immediately-render-on-next.md
deleted file mode 100644
index 69a4c02356..0000000000
--- a/.changeset/fix-react-respect-immediately-render-on-next.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@tiptap/react": patch
----
-
-Respect explicit `immediatelyRender: true` in client-side Next.js. Previously, when running under Next.js (`window.next` present), the `immediatelyRender` option was forced to `false` even when the user explicitly passed `true`, breaking client-only Next.js apps that rely on the editor existing on the first render. The hook now only forces `false` when actual SSR is detected (`typeof window === 'undefined'`), or when running under Next.js with no explicit value.
diff --git a/.changeset/hip-penguins-juggle.md b/.changeset/hip-penguins-juggle.md
deleted file mode 100644
index d0e63bf6d0..0000000000
--- a/.changeset/hip-penguins-juggle.md
+++ /dev/null
@@ -1,14 +0,0 @@
----
-"@tiptap/core": patch
-"@tiptap/react": patch
-"@tiptap/vue-2": patch
-"@tiptap/vue-3": patch
----
-
-fix(nodeview): eliminate unnecessary re-renders, add opt-in position tracking
-
-NodeViews no longer re-render when decorations or position change without
-content changes. Added `trackNodeViewPosition` option — when enabled, the
-component re-renders on every position shift so calls to `getPos()` stay
-current in render output. Removed the internal `nodeViewPositionRegistry`.
-Added shallow prop comparison in `ReactRenderer.updateProps()`.
diff --git a/.changeset/silent-baboons-explain.md b/.changeset/silent-baboons-explain.md
deleted file mode 100644
index f097dddc2c..0000000000
--- a/.changeset/silent-baboons-explain.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@tiptap/markdown": patch
----
-
-Fix adjacent marks of the same type with different attributes being merged during Markdown serialization
diff --git a/.changeset/wet-poets-knock.md b/.changeset/wet-poets-knock.md
deleted file mode 100644
index 2dd192c141..0000000000
--- a/.changeset/wet-poets-knock.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@tiptap/extension-drag-handle-react': patch
----
-
-Fix missing forwarding of getReferencedVirtualElement in DragHandle React component
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 72f873cc02..5a0994c60d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,637 @@
# Releases
+## v3.23.5
+
+### @tiptap/markdown
+
+#### Patch Changes
+
+- 7bf0e73: Fix extra mark tokens after inline atom nodes during Markdown serialization
+- 7bf0e73: Fix adjacent marks of the same type with different attributes being merged during Markdown serialization
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/core
+
+#### Patch Changes
+
+- 7bf0e73: Fix $pos() returning correct node for non-text atom nodes instead of doc node
+- 7bf0e73: fix(nodeview): eliminate unnecessary re-renders, add opt-in position tracking
+
+ NodeViews no longer re-render when decorations or position change without
+ content changes. Added `trackNodeViewPosition` option — when enabled, the
+ component re-renders on every position shift so calls to `getPos()` stay
+ current in render output. Removed the internal `nodeViewPositionRegistry`.
+ Added shallow prop comparison in `ReactRenderer.updateProps()`.
+- @tiptap/pm@3.23.5
+
+### @tiptap/react
+
+#### Patch Changes
+
+- 7bf0e73: Respect explicit `immediatelyRender: true` in client-side Next.js. Previously, when running under Next.js (`window.next` present), the `immediatelyRender` option was forced to `false` even when the user explicitly passed `true`, breaking client-only Next.js apps that rely on the editor existing on the first render. The hook now only forces `false` when actual SSR is detected (`typeof window === 'undefined'`), or when running under Next.js with no explicit value.
+- 7bf0e73: fix(nodeview): eliminate unnecessary re-renders, add opt-in position tracking
+
+ NodeViews no longer re-render when decorations or position change without
+ content changes. Added `trackNodeViewPosition` option — when enabled, the
+ component re-renders on every position shift so calls to `getPos()` stay
+ current in render output. Removed the internal `nodeViewPositionRegistry`.
+ Added shallow prop comparison in `ReactRenderer.updateProps()`.
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/vue-2
+
+#### Patch Changes
+
+- 7bf0e73: fix(nodeview): eliminate unnecessary re-renders, add opt-in position tracking
+
+ NodeViews no longer re-render when decorations or position change without
+ content changes. Added `trackNodeViewPosition` option — when enabled, the
+ component re-renders on every position shift so calls to `getPos()` stay
+ current in render output. Removed the internal `nodeViewPositionRegistry`.
+ Added shallow prop comparison in `ReactRenderer.updateProps()`.
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/vue-3
+
+#### Patch Changes
+
+- 7bf0e73: fix(nodeview): eliminate unnecessary re-renders, add opt-in position tracking
+
+ NodeViews no longer re-render when decorations or position change without
+ content changes. Added `trackNodeViewPosition` option — when enabled, the
+ component re-renders on every position shift so calls to `getPos()` stay
+ current in render output. Removed the internal `nodeViewPositionRegistry`.
+ Added shallow prop comparison in `ReactRenderer.updateProps()`.
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-drag-handle-react
+
+#### Patch Changes
+
+- 7bf0e73: Fix missing forwarding of getReferencedVirtualElement in DragHandle React component
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/react@3.23.5
+ - @tiptap/extension-drag-handle@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-audio
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-blockquote
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-bold
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-bubble-menu
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-code
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-code-block
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-code-block-lowlight
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/extension-code-block@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-collaboration
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-collaboration-caret
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-details
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/extension-text-style@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-document
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-drag-handle
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/extension-collaboration@3.23.5
+ - @tiptap/extension-node-range@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-emoji
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/suggestion@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-file-handler
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/extension-text-style@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-floating-menu
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-hard-break
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-heading
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-highlight
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-horizontal-rule
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-image
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-invisible-characters
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/extension-text-style@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-italic
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-link
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-list
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-mathematics
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-mention
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/suggestion@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-node-range
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-paragraph
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-strike
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-subscript
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-superscript
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-table
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-table-of-contents
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-text
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-text-align
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-text-style
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-twitch
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-typography
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-underline
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extension-unique-id
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-youtube
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+
+### @tiptap/extensions
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/html
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/static-renderer
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/suggestion
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-drag-handle-vue-2
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+ - @tiptap/vue-2@3.23.5
+ - @tiptap/extension-drag-handle@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-drag-handle-vue-3
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+ - @tiptap/vue-3@3.23.5
+ - @tiptap/extension-drag-handle@3.23.5
+ - @tiptap/pm@3.23.5
+
+### @tiptap/extension-list-item
+
+#### Patch Changes
+
+- @tiptap/extension-list@3.23.5
+
+### @tiptap/extension-list-keymap
+
+#### Patch Changes
+
+- @tiptap/extension-list@3.23.5
+
+### @tiptap/extension-task-item
+
+#### Patch Changes
+
+- @tiptap/extension-list@3.23.5
+
+### @tiptap/extension-task-list
+
+#### Patch Changes
+
+- @tiptap/extension-list@3.23.5
+
+### @tiptap/extension-bullet-list
+
+#### Patch Changes
+
+- @tiptap/extension-list@3.23.5
+
+### @tiptap/extension-ordered-list
+
+#### Patch Changes
+
+- @tiptap/extension-list@3.23.5
+
+### @tiptap/extension-table-cell
+
+#### Patch Changes
+
+- @tiptap/extension-table@3.23.5
+
+### @tiptap/extension-table-header
+
+#### Patch Changes
+
+- @tiptap/extension-table@3.23.5
+
+### @tiptap/extension-table-row
+
+#### Patch Changes
+
+- @tiptap/extension-table@3.23.5
+
+### @tiptap/extension-color
+
+#### Patch Changes
+
+- @tiptap/extension-text-style@3.23.5
+
+### @tiptap/extension-font-family
+
+#### Patch Changes
+
+- @tiptap/extension-text-style@3.23.5
+
+### @tiptap/extension-character-count
+
+#### Patch Changes
+
+- @tiptap/extensions@3.23.5
+
+### @tiptap/extension-dropcursor
+
+#### Patch Changes
+
+- @tiptap/extensions@3.23.5
+
+### @tiptap/extension-focus
+
+#### Patch Changes
+
+- @tiptap/extensions@3.23.5
+
+### @tiptap/extension-gapcursor
+
+#### Patch Changes
+
+- @tiptap/extensions@3.23.5
+
+### @tiptap/extension-history
+
+#### Patch Changes
+
+- @tiptap/extensions@3.23.5
+
+### @tiptap/extension-placeholder
+
+#### Patch Changes
+
+- @tiptap/extensions@3.23.5
+
+### @tiptap/starter-kit
+
+#### Patch Changes
+
+- Updated dependencies [7bf0e73]
+- Updated dependencies [7bf0e73]
+ - @tiptap/core@3.23.5
+ - @tiptap/extension-blockquote@3.23.5
+ - @tiptap/extension-bold@3.23.5
+ - @tiptap/extension-code@3.23.5
+ - @tiptap/extension-code-block@3.23.5
+ - @tiptap/extension-document@3.23.5
+ - @tiptap/extension-hard-break@3.23.5
+ - @tiptap/extension-heading@3.23.5
+ - @tiptap/extension-horizontal-rule@3.23.5
+ - @tiptap/extension-italic@3.23.5
+ - @tiptap/extension-link@3.23.5
+ - @tiptap/extension-list@3.23.5
+ - @tiptap/extension-paragraph@3.23.5
+ - @tiptap/extension-strike@3.23.5
+ - @tiptap/extension-text@3.23.5
+ - @tiptap/extension-underline@3.23.5
+ - @tiptap/extensions@3.23.5
+ - @tiptap/extension-list-item@3.23.5
+ - @tiptap/extension-list-keymap@3.23.5
+ - @tiptap/extension-bullet-list@3.23.5
+ - @tiptap/extension-ordered-list@3.23.5
+ - @tiptap/extension-dropcursor@3.23.5
+ - @tiptap/extension-gapcursor@3.23.5
+ - @tiptap/pm@3.23.5
+
## v0.1.3
### @tiptap/server-ai-toolkit
diff --git a/packages-deprecated/extension-character-count/CHANGELOG.md b/packages-deprecated/extension-character-count/CHANGELOG.md
index 9c4aa7332d..7f62e84e17 100644
--- a/packages-deprecated/extension-character-count/CHANGELOG.md
+++ b/packages-deprecated/extension-character-count/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extensions@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages-deprecated/extension-character-count/package.json b/packages-deprecated/extension-character-count/package.json
index 921ba2b75e..6f0bffd972 100644
--- a/packages-deprecated/extension-character-count/package.json
+++ b/packages-deprecated/extension-character-count/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-character-count",
"description": "font family extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages-deprecated/extension-dropcursor/CHANGELOG.md b/packages-deprecated/extension-dropcursor/CHANGELOG.md
index 28dfec6634..dee9999c48 100644
--- a/packages-deprecated/extension-dropcursor/CHANGELOG.md
+++ b/packages-deprecated/extension-dropcursor/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extensions@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages-deprecated/extension-dropcursor/package.json b/packages-deprecated/extension-dropcursor/package.json
index 699afc9306..38eb27d7b0 100644
--- a/packages-deprecated/extension-dropcursor/package.json
+++ b/packages-deprecated/extension-dropcursor/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-dropcursor",
"description": "dropcursor extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages-deprecated/extension-focus/CHANGELOG.md b/packages-deprecated/extension-focus/CHANGELOG.md
index f47afaef3f..8a5dba31b8 100644
--- a/packages-deprecated/extension-focus/CHANGELOG.md
+++ b/packages-deprecated/extension-focus/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extensions@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages-deprecated/extension-focus/package.json b/packages-deprecated/extension-focus/package.json
index fbf0cf2d40..7562097dbf 100644
--- a/packages-deprecated/extension-focus/package.json
+++ b/packages-deprecated/extension-focus/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-focus",
"description": "focus extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages-deprecated/extension-gapcursor/CHANGELOG.md b/packages-deprecated/extension-gapcursor/CHANGELOG.md
index 762c778823..d7221aa11a 100644
--- a/packages-deprecated/extension-gapcursor/CHANGELOG.md
+++ b/packages-deprecated/extension-gapcursor/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extensions@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages-deprecated/extension-gapcursor/package.json b/packages-deprecated/extension-gapcursor/package.json
index 6aa19a9dc9..e752dd9f65 100644
--- a/packages-deprecated/extension-gapcursor/package.json
+++ b/packages-deprecated/extension-gapcursor/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-gapcursor",
"description": "gapcursor extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages-deprecated/extension-history/CHANGELOG.md b/packages-deprecated/extension-history/CHANGELOG.md
index 5f5a63e0de..1f733988b4 100644
--- a/packages-deprecated/extension-history/CHANGELOG.md
+++ b/packages-deprecated/extension-history/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extensions@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages-deprecated/extension-history/package.json b/packages-deprecated/extension-history/package.json
index a2153e98be..984227e9e8 100644
--- a/packages-deprecated/extension-history/package.json
+++ b/packages-deprecated/extension-history/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-history",
"description": "history extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages-deprecated/extension-list-item/CHANGELOG.md b/packages-deprecated/extension-list-item/CHANGELOG.md
index 215747ed59..ff14e49876 100644
--- a/packages-deprecated/extension-list-item/CHANGELOG.md
+++ b/packages-deprecated/extension-list-item/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extension-list@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages-deprecated/extension-list-item/package.json b/packages-deprecated/extension-list-item/package.json
index c21593cc6c..2e42f51925 100644
--- a/packages-deprecated/extension-list-item/package.json
+++ b/packages-deprecated/extension-list-item/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-list-item",
"description": "list item extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages-deprecated/extension-list-keymap/CHANGELOG.md b/packages-deprecated/extension-list-keymap/CHANGELOG.md
index 5391543b94..7155f376e2 100644
--- a/packages-deprecated/extension-list-keymap/CHANGELOG.md
+++ b/packages-deprecated/extension-list-keymap/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extension-list@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages-deprecated/extension-list-keymap/package.json b/packages-deprecated/extension-list-keymap/package.json
index fe13c946f4..bac879b3fb 100644
--- a/packages-deprecated/extension-list-keymap/package.json
+++ b/packages-deprecated/extension-list-keymap/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-list-keymap",
"description": "list keymap extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages-deprecated/extension-placeholder/CHANGELOG.md b/packages-deprecated/extension-placeholder/CHANGELOG.md
index 160d4e06d7..5a11817513 100644
--- a/packages-deprecated/extension-placeholder/CHANGELOG.md
+++ b/packages-deprecated/extension-placeholder/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extensions@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages-deprecated/extension-placeholder/package.json b/packages-deprecated/extension-placeholder/package.json
index 13306ba287..43b9cfb451 100644
--- a/packages-deprecated/extension-placeholder/package.json
+++ b/packages-deprecated/extension-placeholder/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-placeholder",
"description": "placeholder extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages-deprecated/extension-table-cell/CHANGELOG.md b/packages-deprecated/extension-table-cell/CHANGELOG.md
index 604cd2dc84..1de5cea974 100644
--- a/packages-deprecated/extension-table-cell/CHANGELOG.md
+++ b/packages-deprecated/extension-table-cell/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extension-table@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages-deprecated/extension-table-cell/package.json b/packages-deprecated/extension-table-cell/package.json
index b24719f39d..4ca742a0bd 100644
--- a/packages-deprecated/extension-table-cell/package.json
+++ b/packages-deprecated/extension-table-cell/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-table-cell",
"description": "table cell extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages-deprecated/extension-table-header/CHANGELOG.md b/packages-deprecated/extension-table-header/CHANGELOG.md
index 931e003a33..0cb07cee83 100644
--- a/packages-deprecated/extension-table-header/CHANGELOG.md
+++ b/packages-deprecated/extension-table-header/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extension-table@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages-deprecated/extension-table-header/package.json b/packages-deprecated/extension-table-header/package.json
index 3f5459ed4e..36374bff4d 100644
--- a/packages-deprecated/extension-table-header/package.json
+++ b/packages-deprecated/extension-table-header/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-table-header",
"description": "table cell extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages-deprecated/extension-table-row/CHANGELOG.md b/packages-deprecated/extension-table-row/CHANGELOG.md
index dcb6563a19..9e5591aab8 100644
--- a/packages-deprecated/extension-table-row/CHANGELOG.md
+++ b/packages-deprecated/extension-table-row/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extension-table@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages-deprecated/extension-table-row/package.json b/packages-deprecated/extension-table-row/package.json
index 5a462dca1f..93bcd4bb6e 100644
--- a/packages-deprecated/extension-table-row/package.json
+++ b/packages-deprecated/extension-table-row/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-table-row",
"description": "table row extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages-deprecated/extension-task-item/CHANGELOG.md b/packages-deprecated/extension-task-item/CHANGELOG.md
index 0ad15e14a3..f26b50e8ce 100644
--- a/packages-deprecated/extension-task-item/CHANGELOG.md
+++ b/packages-deprecated/extension-task-item/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extension-list@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages-deprecated/extension-task-item/package.json b/packages-deprecated/extension-task-item/package.json
index a6eda18e99..64a65c7eef 100644
--- a/packages-deprecated/extension-task-item/package.json
+++ b/packages-deprecated/extension-task-item/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-task-item",
"description": "task item extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages-deprecated/extension-task-list/CHANGELOG.md b/packages-deprecated/extension-task-list/CHANGELOG.md
index fb23b7fd34..be2dc2a02f 100644
--- a/packages-deprecated/extension-task-list/CHANGELOG.md
+++ b/packages-deprecated/extension-task-list/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extension-list@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages-deprecated/extension-task-list/package.json b/packages-deprecated/extension-task-list/package.json
index 1654561edc..1767417dfa 100644
--- a/packages-deprecated/extension-task-list/package.json
+++ b/packages-deprecated/extension-task-list/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-task-list",
"description": "task list extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md
index 899545a181..7bd6b9fd6e 100644
--- a/packages/core/CHANGELOG.md
+++ b/packages/core/CHANGELOG.md
@@ -1,5 +1,20 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- 835caf5: Fix $pos() returning correct node for non-text atom nodes instead of doc node
+- 95e138c: fix(nodeview): eliminate unnecessary re-renders, add opt-in position tracking
+
+ NodeViews no longer re-render when decorations or position change without
+ content changes. Added `trackNodeViewPosition` option — when enabled, the
+ component re-renders on every position shift so calls to `getPos()` stay
+ current in render output. Removed the internal `nodeViewPositionRegistry`.
+ Added shallow prop comparison in `ReactRenderer.updateProps()`.
+
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/core/package.json b/packages/core/package.json
index eaa2229891..cd9d70a724 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/core",
"description": "headless rich text editor",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-audio/CHANGELOG.md b/packages/extension-audio/CHANGELOG.md
index 2fabb4e689..46fb19330c 100644
--- a/packages/extension-audio/CHANGELOG.md
+++ b/packages/extension-audio/CHANGELOG.md
@@ -1,5 +1,13 @@
# @tiptap/extension-audio
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-audio/package.json b/packages/extension-audio/package.json
index 9f0aaaf791..47f84b9058 100644
--- a/packages/extension-audio/package.json
+++ b/packages/extension-audio/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-audio",
"description": "audio extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-blockquote/CHANGELOG.md b/packages/extension-blockquote/CHANGELOG.md
index 2955645c20..cddf974352 100644
--- a/packages/extension-blockquote/CHANGELOG.md
+++ b/packages/extension-blockquote/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-blockquote/package.json b/packages/extension-blockquote/package.json
index 2d6d0c894f..a6e4bd9cd0 100644
--- a/packages/extension-blockquote/package.json
+++ b/packages/extension-blockquote/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-blockquote",
"description": "blockquote extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-bold/CHANGELOG.md b/packages/extension-bold/CHANGELOG.md
index 1aec199b76..532954a1f7 100644
--- a/packages/extension-bold/CHANGELOG.md
+++ b/packages/extension-bold/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-bold/package.json b/packages/extension-bold/package.json
index e4538fa121..e603071e32 100644
--- a/packages/extension-bold/package.json
+++ b/packages/extension-bold/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-bold",
"description": "bold extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-bubble-menu/CHANGELOG.md b/packages/extension-bubble-menu/CHANGELOG.md
index a237714a38..88fa24080b 100644
--- a/packages/extension-bubble-menu/CHANGELOG.md
+++ b/packages/extension-bubble-menu/CHANGELOG.md
@@ -1,5 +1,14 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-bubble-menu/package.json b/packages/extension-bubble-menu/package.json
index d50154c3ef..238f1d496a 100644
--- a/packages/extension-bubble-menu/package.json
+++ b/packages/extension-bubble-menu/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-bubble-menu",
"description": "bubble-menu extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-bullet-list/CHANGELOG.md b/packages/extension-bullet-list/CHANGELOG.md
index cfeb337dc4..5ae6d0e232 100644
--- a/packages/extension-bullet-list/CHANGELOG.md
+++ b/packages/extension-bullet-list/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extension-list@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-bullet-list/package.json b/packages/extension-bullet-list/package.json
index 2bcbde56b6..2dfbb0b955 100644
--- a/packages/extension-bullet-list/package.json
+++ b/packages/extension-bullet-list/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-bullet-list",
"description": "bullet list extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-code-block-lowlight/CHANGELOG.md b/packages/extension-code-block-lowlight/CHANGELOG.md
index d2b697eb24..469c232511 100644
--- a/packages/extension-code-block-lowlight/CHANGELOG.md
+++ b/packages/extension-code-block-lowlight/CHANGELOG.md
@@ -1,5 +1,15 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/extension-code-block@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-code-block-lowlight/package.json b/packages/extension-code-block-lowlight/package.json
index 1c80caf09a..b04dbcdbdf 100644
--- a/packages/extension-code-block-lowlight/package.json
+++ b/packages/extension-code-block-lowlight/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-code-block-lowlight",
"description": "code block extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-code-block/CHANGELOG.md b/packages/extension-code-block/CHANGELOG.md
index 53998719df..835d94b9fe 100644
--- a/packages/extension-code-block/CHANGELOG.md
+++ b/packages/extension-code-block/CHANGELOG.md
@@ -1,5 +1,14 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-code-block/package.json b/packages/extension-code-block/package.json
index 2ada481eae..61606f149b 100644
--- a/packages/extension-code-block/package.json
+++ b/packages/extension-code-block/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-code-block",
"description": "code block extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-code/CHANGELOG.md b/packages/extension-code/CHANGELOG.md
index 5a9c1f5875..d05dfb65a0 100644
--- a/packages/extension-code/CHANGELOG.md
+++ b/packages/extension-code/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-code/package.json b/packages/extension-code/package.json
index edcc8e6dc9..afa3cd6e30 100644
--- a/packages/extension-code/package.json
+++ b/packages/extension-code/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-code",
"description": "code extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-collaboration-caret/CHANGELOG.md b/packages/extension-collaboration-caret/CHANGELOG.md
index eee3d342f8..f3806865f7 100644
--- a/packages/extension-collaboration-caret/CHANGELOG.md
+++ b/packages/extension-collaboration-caret/CHANGELOG.md
@@ -1,5 +1,14 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-collaboration-caret/package.json b/packages/extension-collaboration-caret/package.json
index d02937be1e..417e9629f8 100644
--- a/packages/extension-collaboration-caret/package.json
+++ b/packages/extension-collaboration-caret/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-collaboration-caret",
"description": "collaboration caret extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-collaboration/CHANGELOG.md b/packages/extension-collaboration/CHANGELOG.md
index 5287ff28b7..7b5c4a515a 100644
--- a/packages/extension-collaboration/CHANGELOG.md
+++ b/packages/extension-collaboration/CHANGELOG.md
@@ -1,5 +1,14 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-collaboration/package.json b/packages/extension-collaboration/package.json
index f08e9bc56b..2e1375b26a 100644
--- a/packages/extension-collaboration/package.json
+++ b/packages/extension-collaboration/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-collaboration",
"description": "collaboration extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-color/CHANGELOG.md b/packages/extension-color/CHANGELOG.md
index 45e3de003e..471107d3c0 100644
--- a/packages/extension-color/CHANGELOG.md
+++ b/packages/extension-color/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extension-text-style@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-color/package.json b/packages/extension-color/package.json
index e0bb6ae681..06da66537a 100644
--- a/packages/extension-color/package.json
+++ b/packages/extension-color/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-color",
"description": "text color extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-details/CHANGELOG.md b/packages/extension-details/CHANGELOG.md
index 44fcf3c8bc..236e427754 100644
--- a/packages/extension-details/CHANGELOG.md
+++ b/packages/extension-details/CHANGELOG.md
@@ -1,5 +1,15 @@
# @tiptap/extension-details
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/extension-text-style@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-details/package.json b/packages/extension-details/package.json
index b0c2a787c9..851044d0b2 100644
--- a/packages/extension-details/package.json
+++ b/packages/extension-details/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-details",
"description": "details extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev/api/nodes/details",
"keywords": [
"tiptap",
diff --git a/packages/extension-document/CHANGELOG.md b/packages/extension-document/CHANGELOG.md
index 77706ba446..e73b07c1d7 100644
--- a/packages/extension-document/CHANGELOG.md
+++ b/packages/extension-document/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-document/package.json b/packages/extension-document/package.json
index 3d087ee513..83425afccc 100644
--- a/packages/extension-document/package.json
+++ b/packages/extension-document/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-document",
"description": "document extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-drag-handle-react/CHANGELOG.md b/packages/extension-drag-handle-react/CHANGELOG.md
index 7a440efd51..d26a7f1d82 100644
--- a/packages/extension-drag-handle-react/CHANGELOG.md
+++ b/packages/extension-drag-handle-react/CHANGELOG.md
@@ -1,5 +1,16 @@
# @tiptap/extension-drag-handle-react
+## 3.23.5
+
+### Patch Changes
+
+- ec1afc3: Fix missing forwarding of getReferencedVirtualElement in DragHandle React component
+- Updated dependencies [b5f34fc]
+- Updated dependencies [95e138c]
+ - @tiptap/react@3.23.5
+ - @tiptap/extension-drag-handle@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-drag-handle-react/package.json b/packages/extension-drag-handle-react/package.json
index 3062c1d207..314e25b495 100644
--- a/packages/extension-drag-handle-react/package.json
+++ b/packages/extension-drag-handle-react/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-drag-handle-react",
"description": "drag handle extension for tiptap with react",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-drag-handle-vue-2/CHANGELOG.md b/packages/extension-drag-handle-vue-2/CHANGELOG.md
index c37dd4550e..3b067a5952 100644
--- a/packages/extension-drag-handle-vue-2/CHANGELOG.md
+++ b/packages/extension-drag-handle-vue-2/CHANGELOG.md
@@ -1,5 +1,14 @@
# @tiptap/extension-drag-handle-vue-2
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [95e138c]
+ - @tiptap/vue-2@3.23.5
+ - @tiptap/extension-drag-handle@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-drag-handle-vue-2/package.json b/packages/extension-drag-handle-vue-2/package.json
index 9be2334c24..ab87133edc 100644
--- a/packages/extension-drag-handle-vue-2/package.json
+++ b/packages/extension-drag-handle-vue-2/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-drag-handle-vue-2",
"description": "drag handle extension for tiptap with vue 2",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-drag-handle-vue-3/CHANGELOG.md b/packages/extension-drag-handle-vue-3/CHANGELOG.md
index 3b366e738e..61e5cfa4f2 100644
--- a/packages/extension-drag-handle-vue-3/CHANGELOG.md
+++ b/packages/extension-drag-handle-vue-3/CHANGELOG.md
@@ -1,5 +1,14 @@
# @tiptap/extension-drag-handle-vue-3
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [95e138c]
+ - @tiptap/vue-3@3.23.5
+ - @tiptap/extension-drag-handle@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-drag-handle-vue-3/package.json b/packages/extension-drag-handle-vue-3/package.json
index 7d36c9cfcd..165a355147 100644
--- a/packages/extension-drag-handle-vue-3/package.json
+++ b/packages/extension-drag-handle-vue-3/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-drag-handle-vue-3",
"description": "drag handle extension for tiptap with vue 3",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-drag-handle/CHANGELOG.md b/packages/extension-drag-handle/CHANGELOG.md
index 61c05d43f8..8d30c2fb2d 100644
--- a/packages/extension-drag-handle/CHANGELOG.md
+++ b/packages/extension-drag-handle/CHANGELOG.md
@@ -1,5 +1,16 @@
# @tiptap/extension-drag-handle
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/extension-collaboration@3.23.5
+ - @tiptap/extension-node-range@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-drag-handle/package.json b/packages/extension-drag-handle/package.json
index 7bc0fab2e0..b00935a10b 100644
--- a/packages/extension-drag-handle/package.json
+++ b/packages/extension-drag-handle/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-drag-handle",
"description": "drag handle extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev/docs/editor/extensions/functionality/drag-handle",
"keywords": [
"tiptap",
diff --git a/packages/extension-emoji/CHANGELOG.md b/packages/extension-emoji/CHANGELOG.md
index 8b3ba0f9d5..dc5d48b8e2 100644
--- a/packages/extension-emoji/CHANGELOG.md
+++ b/packages/extension-emoji/CHANGELOG.md
@@ -1,5 +1,15 @@
# @tiptap/extension-emoji
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/suggestion@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-emoji/package.json b/packages/extension-emoji/package.json
index 52eee0b59d..002eb5fafa 100644
--- a/packages/extension-emoji/package.json
+++ b/packages/extension-emoji/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-emoji",
"description": "emoji extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev/api/nodes/emoji",
"keywords": [
"tiptap",
diff --git a/packages/extension-file-handler/CHANGELOG.md b/packages/extension-file-handler/CHANGELOG.md
index d6eb5cfbc0..1eca9da46b 100644
--- a/packages/extension-file-handler/CHANGELOG.md
+++ b/packages/extension-file-handler/CHANGELOG.md
@@ -1,5 +1,15 @@
# @tiptap/extension-file-handler
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/extension-text-style@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-file-handler/package.json b/packages/extension-file-handler/package.json
index 9dc80211bd..3754e14fb4 100644
--- a/packages/extension-file-handler/package.json
+++ b/packages/extension-file-handler/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-file-handler",
"description": "file handler extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev/docs/editor/extensions/functionality/filehandler",
"keywords": [
"tiptap",
diff --git a/packages/extension-floating-menu/CHANGELOG.md b/packages/extension-floating-menu/CHANGELOG.md
index ffc420f546..aae81e3b83 100644
--- a/packages/extension-floating-menu/CHANGELOG.md
+++ b/packages/extension-floating-menu/CHANGELOG.md
@@ -1,5 +1,14 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-floating-menu/package.json b/packages/extension-floating-menu/package.json
index 51bbac1d0f..213ec83139 100644
--- a/packages/extension-floating-menu/package.json
+++ b/packages/extension-floating-menu/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-floating-menu",
"description": "floating-menu extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-font-family/CHANGELOG.md b/packages/extension-font-family/CHANGELOG.md
index c45b42dffb..6dd13ba72e 100644
--- a/packages/extension-font-family/CHANGELOG.md
+++ b/packages/extension-font-family/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extension-text-style@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-font-family/package.json b/packages/extension-font-family/package.json
index b68ed0b156..2cc3e02560 100644
--- a/packages/extension-font-family/package.json
+++ b/packages/extension-font-family/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-font-family",
"description": "font family extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-hard-break/CHANGELOG.md b/packages/extension-hard-break/CHANGELOG.md
index 05c3b7a6f1..e436961bb0 100644
--- a/packages/extension-hard-break/CHANGELOG.md
+++ b/packages/extension-hard-break/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-hard-break/package.json b/packages/extension-hard-break/package.json
index 6b7779234b..18799451b0 100644
--- a/packages/extension-hard-break/package.json
+++ b/packages/extension-hard-break/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-hard-break",
"description": "hard break extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-heading/CHANGELOG.md b/packages/extension-heading/CHANGELOG.md
index c41219a203..6c1457349b 100644
--- a/packages/extension-heading/CHANGELOG.md
+++ b/packages/extension-heading/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-heading/package.json b/packages/extension-heading/package.json
index bf56ff9208..2d796d4ec1 100644
--- a/packages/extension-heading/package.json
+++ b/packages/extension-heading/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-heading",
"description": "heading extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-highlight/CHANGELOG.md b/packages/extension-highlight/CHANGELOG.md
index 88bd109185..ab3ff2694c 100644
--- a/packages/extension-highlight/CHANGELOG.md
+++ b/packages/extension-highlight/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-highlight/package.json b/packages/extension-highlight/package.json
index 3657b5be1f..c0a137872e 100644
--- a/packages/extension-highlight/package.json
+++ b/packages/extension-highlight/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-highlight",
"description": "highlight extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-horizontal-rule/CHANGELOG.md b/packages/extension-horizontal-rule/CHANGELOG.md
index 3afd8f2d79..a334e5bbde 100644
--- a/packages/extension-horizontal-rule/CHANGELOG.md
+++ b/packages/extension-horizontal-rule/CHANGELOG.md
@@ -1,5 +1,14 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-horizontal-rule/package.json b/packages/extension-horizontal-rule/package.json
index aaf5775007..99e83c07b7 100644
--- a/packages/extension-horizontal-rule/package.json
+++ b/packages/extension-horizontal-rule/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-horizontal-rule",
"description": "horizontal rule extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-image/CHANGELOG.md b/packages/extension-image/CHANGELOG.md
index 155aa6f1ea..b883ce6d0c 100644
--- a/packages/extension-image/CHANGELOG.md
+++ b/packages/extension-image/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-image/package.json b/packages/extension-image/package.json
index f3c94224ac..9a7d0051d6 100644
--- a/packages/extension-image/package.json
+++ b/packages/extension-image/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-image",
"description": "image extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-invisible-characters/CHANGELOG.md b/packages/extension-invisible-characters/CHANGELOG.md
index 07dc6e35b3..7be73aa8ab 100644
--- a/packages/extension-invisible-characters/CHANGELOG.md
+++ b/packages/extension-invisible-characters/CHANGELOG.md
@@ -1,5 +1,15 @@
# @tiptap/extension-invisible-characters
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/extension-text-style@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-invisible-characters/package.json b/packages/extension-invisible-characters/package.json
index b845f4e5dd..ae245a6049 100644
--- a/packages/extension-invisible-characters/package.json
+++ b/packages/extension-invisible-characters/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-invisible-characters",
"description": "invisible characters extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev/docs/editor/extensions/functionality/invisiblecharacters",
"keywords": [
"tiptap",
diff --git a/packages/extension-italic/CHANGELOG.md b/packages/extension-italic/CHANGELOG.md
index 3b04172834..e406112665 100644
--- a/packages/extension-italic/CHANGELOG.md
+++ b/packages/extension-italic/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-italic/package.json b/packages/extension-italic/package.json
index 597e2d5a8d..c5f52be53f 100644
--- a/packages/extension-italic/package.json
+++ b/packages/extension-italic/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-italic",
"description": "italic extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-link/CHANGELOG.md b/packages/extension-link/CHANGELOG.md
index 8e09db7cbc..702467b28d 100644
--- a/packages/extension-link/CHANGELOG.md
+++ b/packages/extension-link/CHANGELOG.md
@@ -1,5 +1,14 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-link/package.json b/packages/extension-link/package.json
index 27a8698460..a3ed9fd887 100644
--- a/packages/extension-link/package.json
+++ b/packages/extension-link/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-link",
"description": "link extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-list/CHANGELOG.md b/packages/extension-list/CHANGELOG.md
index 558291b955..e002ccecc5 100644
--- a/packages/extension-list/CHANGELOG.md
+++ b/packages/extension-list/CHANGELOG.md
@@ -1,5 +1,14 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-list/package.json b/packages/extension-list/package.json
index a409a89bc3..ca5af5c62b 100644
--- a/packages/extension-list/package.json
+++ b/packages/extension-list/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-list",
"description": "List extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-mathematics/CHANGELOG.md b/packages/extension-mathematics/CHANGELOG.md
index 01a6fd0989..5f51a776e5 100644
--- a/packages/extension-mathematics/CHANGELOG.md
+++ b/packages/extension-mathematics/CHANGELOG.md
@@ -1,5 +1,14 @@
# @tiptap/extension-mathematics
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-mathematics/package.json b/packages/extension-mathematics/package.json
index 8c86149213..07fe5dc51a 100644
--- a/packages/extension-mathematics/package.json
+++ b/packages/extension-mathematics/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-mathematics",
"description": "latex math extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev/api/extensions/mathematics",
"keywords": [
"tiptap",
diff --git a/packages/extension-mention/CHANGELOG.md b/packages/extension-mention/CHANGELOG.md
index ce20c6c365..e1f1369696 100644
--- a/packages/extension-mention/CHANGELOG.md
+++ b/packages/extension-mention/CHANGELOG.md
@@ -1,5 +1,15 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/suggestion@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-mention/package.json b/packages/extension-mention/package.json
index c0073c8bdc..9267ab9791 100644
--- a/packages/extension-mention/package.json
+++ b/packages/extension-mention/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-mention",
"description": "mention extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-node-range/CHANGELOG.md b/packages/extension-node-range/CHANGELOG.md
index f3ed5d4edb..9c673c2948 100644
--- a/packages/extension-node-range/CHANGELOG.md
+++ b/packages/extension-node-range/CHANGELOG.md
@@ -1,5 +1,14 @@
# @tiptap/extension-node-range
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-node-range/package.json b/packages/extension-node-range/package.json
index 3b611c84f4..f0adda3ca0 100644
--- a/packages/extension-node-range/package.json
+++ b/packages/extension-node-range/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-node-range",
"description": "node range extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-ordered-list/CHANGELOG.md b/packages/extension-ordered-list/CHANGELOG.md
index bfff5b9106..c7f17738d5 100644
--- a/packages/extension-ordered-list/CHANGELOG.md
+++ b/packages/extension-ordered-list/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- @tiptap/extension-list@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-ordered-list/package.json b/packages/extension-ordered-list/package.json
index e671734ae6..9980a6ea1d 100644
--- a/packages/extension-ordered-list/package.json
+++ b/packages/extension-ordered-list/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-ordered-list",
"description": "ordered list extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-paragraph/CHANGELOG.md b/packages/extension-paragraph/CHANGELOG.md
index 84ce5824c9..1e4b3f6098 100644
--- a/packages/extension-paragraph/CHANGELOG.md
+++ b/packages/extension-paragraph/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-paragraph/package.json b/packages/extension-paragraph/package.json
index d33f46e756..897306c82f 100644
--- a/packages/extension-paragraph/package.json
+++ b/packages/extension-paragraph/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-paragraph",
"description": "paragraph extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-strike/CHANGELOG.md b/packages/extension-strike/CHANGELOG.md
index ec68df2a6a..a908481ae6 100644
--- a/packages/extension-strike/CHANGELOG.md
+++ b/packages/extension-strike/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-strike/package.json b/packages/extension-strike/package.json
index 5fbe59e4af..cc002e549b 100644
--- a/packages/extension-strike/package.json
+++ b/packages/extension-strike/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-strike",
"description": "strike extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-subscript/CHANGELOG.md b/packages/extension-subscript/CHANGELOG.md
index 437ac90c26..319e5bc386 100644
--- a/packages/extension-subscript/CHANGELOG.md
+++ b/packages/extension-subscript/CHANGELOG.md
@@ -1,5 +1,14 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-subscript/package.json b/packages/extension-subscript/package.json
index 32ea4e3d81..a26607859d 100644
--- a/packages/extension-subscript/package.json
+++ b/packages/extension-subscript/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-subscript",
"description": "subscript extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-superscript/CHANGELOG.md b/packages/extension-superscript/CHANGELOG.md
index e4dafcd2d3..562daab7c5 100644
--- a/packages/extension-superscript/CHANGELOG.md
+++ b/packages/extension-superscript/CHANGELOG.md
@@ -1,5 +1,14 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-superscript/package.json b/packages/extension-superscript/package.json
index 757279ecd6..fa2a5293ad 100644
--- a/packages/extension-superscript/package.json
+++ b/packages/extension-superscript/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-superscript",
"description": "superscript extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-table-of-contents/CHANGELOG.md b/packages/extension-table-of-contents/CHANGELOG.md
index 4527359401..8bdb05fc80 100644
--- a/packages/extension-table-of-contents/CHANGELOG.md
+++ b/packages/extension-table-of-contents/CHANGELOG.md
@@ -1,5 +1,14 @@
# @tiptap/extension-table-of-contents
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-table-of-contents/package.json b/packages/extension-table-of-contents/package.json
index 0c4243902e..5ba2aff79f 100644
--- a/packages/extension-table-of-contents/package.json
+++ b/packages/extension-table-of-contents/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-table-of-contents",
"description": "table of contents extension for Tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev/docs/editor/extensions/functionality/table-of-contents",
"keywords": [
"tiptap",
diff --git a/packages/extension-table/CHANGELOG.md b/packages/extension-table/CHANGELOG.md
index 73fe1f7f52..1da77ffa18 100644
--- a/packages/extension-table/CHANGELOG.md
+++ b/packages/extension-table/CHANGELOG.md
@@ -1,5 +1,14 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-table/package.json b/packages/extension-table/package.json
index 577bf0ff8d..8e0f71a548 100644
--- a/packages/extension-table/package.json
+++ b/packages/extension-table/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-table",
"description": "table extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-text-align/CHANGELOG.md b/packages/extension-text-align/CHANGELOG.md
index 9d168e7928..59bee50666 100644
--- a/packages/extension-text-align/CHANGELOG.md
+++ b/packages/extension-text-align/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-text-align/package.json b/packages/extension-text-align/package.json
index e143404dcf..f674d8bd40 100644
--- a/packages/extension-text-align/package.json
+++ b/packages/extension-text-align/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-text-align",
"description": "text align extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-text-style/CHANGELOG.md b/packages/extension-text-style/CHANGELOG.md
index d04bffe20a..50dae94ead 100644
--- a/packages/extension-text-style/CHANGELOG.md
+++ b/packages/extension-text-style/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-text-style/package.json b/packages/extension-text-style/package.json
index b959fbed29..bbb200ba8b 100644
--- a/packages/extension-text-style/package.json
+++ b/packages/extension-text-style/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-text-style",
"description": "text style extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-text/CHANGELOG.md b/packages/extension-text/CHANGELOG.md
index e2fec7bd1f..cd1f91287c 100644
--- a/packages/extension-text/CHANGELOG.md
+++ b/packages/extension-text/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-text/package.json b/packages/extension-text/package.json
index 1c8d4ab7a4..350033c6b2 100644
--- a/packages/extension-text/package.json
+++ b/packages/extension-text/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-text",
"description": "text extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-twitch/CHANGELOG.md b/packages/extension-twitch/CHANGELOG.md
index 9b09a580b1..153a882f05 100644
--- a/packages/extension-twitch/CHANGELOG.md
+++ b/packages/extension-twitch/CHANGELOG.md
@@ -1,5 +1,13 @@
# @tiptap/extension-twitch
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-twitch/package.json b/packages/extension-twitch/package.json
index b5ec72475d..b53f59c030 100644
--- a/packages/extension-twitch/package.json
+++ b/packages/extension-twitch/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-twitch",
"description": "a twitch embed extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-typography/CHANGELOG.md b/packages/extension-typography/CHANGELOG.md
index 44e4ce0bc2..8f64405158 100644
--- a/packages/extension-typography/CHANGELOG.md
+++ b/packages/extension-typography/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-typography/package.json b/packages/extension-typography/package.json
index d3b61a7b74..e2cd855e6a 100644
--- a/packages/extension-typography/package.json
+++ b/packages/extension-typography/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-typography",
"description": "typography extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-underline/CHANGELOG.md b/packages/extension-underline/CHANGELOG.md
index 82f90a5f9f..352719ed72 100644
--- a/packages/extension-underline/CHANGELOG.md
+++ b/packages/extension-underline/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-underline/package.json b/packages/extension-underline/package.json
index 2b98a3ee4f..be3511473d 100644
--- a/packages/extension-underline/package.json
+++ b/packages/extension-underline/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-underline",
"description": "underline extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extension-unique-id/CHANGELOG.md b/packages/extension-unique-id/CHANGELOG.md
index 4b2d0a4fb2..b0dabb584b 100644
--- a/packages/extension-unique-id/CHANGELOG.md
+++ b/packages/extension-unique-id/CHANGELOG.md
@@ -1,5 +1,14 @@
# @tiptap/extension-unique-id
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-unique-id/package.json b/packages/extension-unique-id/package.json
index 7a24bc48ae..182c0992eb 100644
--- a/packages/extension-unique-id/package.json
+++ b/packages/extension-unique-id/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-unique-id",
"description": "unique id extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev/api/extensions/unique-id",
"keywords": [
"tiptap",
diff --git a/packages/extension-youtube/CHANGELOG.md b/packages/extension-youtube/CHANGELOG.md
index f3e49592e4..629dcff77a 100644
--- a/packages/extension-youtube/CHANGELOG.md
+++ b/packages/extension-youtube/CHANGELOG.md
@@ -1,5 +1,13 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extension-youtube/package.json b/packages/extension-youtube/package.json
index 27b637097c..ce0a53812f 100644
--- a/packages/extension-youtube/package.json
+++ b/packages/extension-youtube/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-youtube",
"description": "a youtube embed extension for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/extensions/CHANGELOG.md b/packages/extensions/CHANGELOG.md
index 20c73cc919..db10b3a348 100644
--- a/packages/extensions/CHANGELOG.md
+++ b/packages/extensions/CHANGELOG.md
@@ -1,5 +1,14 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/extensions/package.json b/packages/extensions/package.json
index 01cc343c87..e8e9b22d33 100644
--- a/packages/extensions/package.json
+++ b/packages/extensions/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/extensions",
"description": "various extensions for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/html/CHANGELOG.md b/packages/html/CHANGELOG.md
index db467dca63..b535f1b72d 100644
--- a/packages/html/CHANGELOG.md
+++ b/packages/html/CHANGELOG.md
@@ -1,5 +1,14 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/html/package.json b/packages/html/package.json
index 0c119ad431..d297723b51 100644
--- a/packages/html/package.json
+++ b/packages/html/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/html",
"description": "utility package to render tiptap JSON as HTML",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/markdown/CHANGELOG.md b/packages/markdown/CHANGELOG.md
index 6db93762ae..fd9d5258c2 100644
--- a/packages/markdown/CHANGELOG.md
+++ b/packages/markdown/CHANGELOG.md
@@ -1,5 +1,16 @@
# @tiptap/markdown
+## 3.23.5
+
+### Patch Changes
+
+- 6abd10c: Fix extra mark tokens after inline atom nodes during Markdown serialization
+- 7bf0e73: Fix adjacent marks of the same type with different attributes being merged during Markdown serialization
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/markdown/package.json b/packages/markdown/package.json
index bbb23bc3af..2b9c969de3 100644
--- a/packages/markdown/package.json
+++ b/packages/markdown/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/markdown",
"description": "markdown parser and serializer for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/pm/CHANGELOG.md b/packages/pm/CHANGELOG.md
index 73c6554344..4be9cb81d5 100644
--- a/packages/pm/CHANGELOG.md
+++ b/packages/pm/CHANGELOG.md
@@ -1,5 +1,7 @@
# Change Log
+## 3.23.5
+
## 3.23.4
## 3.23.3
diff --git a/packages/pm/package.json b/packages/pm/package.json
index 45a3d7ccf9..4940ecd726 100644
--- a/packages/pm/package.json
+++ b/packages/pm/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/pm",
"description": "prosemirror wrapper package for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md
index 1cdb47ab37..2b57e28fa8 100644
--- a/packages/react/CHANGELOG.md
+++ b/packages/react/CHANGELOG.md
@@ -1,5 +1,23 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- b5f34fc: Respect explicit `immediatelyRender: true` in client-side Next.js. Previously, when running under Next.js (`window.next` present), the `immediatelyRender` option was forced to `false` even when the user explicitly passed `true`, breaking client-only Next.js apps that rely on the editor existing on the first render. The hook now only forces `false` when actual SSR is detected (`typeof window === 'undefined'`), or when running under Next.js with no explicit value.
+- 95e138c: fix(nodeview): eliminate unnecessary re-renders, add opt-in position tracking
+
+ NodeViews no longer re-render when decorations or position change without
+ content changes. Added `trackNodeViewPosition` option — when enabled, the
+ component re-renders on every position shift so calls to `getPos()` stay
+ current in render output. Removed the internal `nodeViewPositionRegistry`.
+ Added shallow prop comparison in `ReactRenderer.updateProps()`.
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/react/package.json b/packages/react/package.json
index 1d588dba92..a27f7a6c91 100644
--- a/packages/react/package.json
+++ b/packages/react/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/react",
"description": "React components for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/starter-kit/CHANGELOG.md b/packages/starter-kit/CHANGELOG.md
index 82b62c79c4..1c8d71af51 100644
--- a/packages/starter-kit/CHANGELOG.md
+++ b/packages/starter-kit/CHANGELOG.md
@@ -1,5 +1,36 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/extension-blockquote@3.23.5
+ - @tiptap/extension-bold@3.23.5
+ - @tiptap/extension-code@3.23.5
+ - @tiptap/extension-code-block@3.23.5
+ - @tiptap/extension-document@3.23.5
+ - @tiptap/extension-hard-break@3.23.5
+ - @tiptap/extension-heading@3.23.5
+ - @tiptap/extension-horizontal-rule@3.23.5
+ - @tiptap/extension-italic@3.23.5
+ - @tiptap/extension-link@3.23.5
+ - @tiptap/extension-list@3.23.5
+ - @tiptap/extension-paragraph@3.23.5
+ - @tiptap/extension-strike@3.23.5
+ - @tiptap/extension-text@3.23.5
+ - @tiptap/extension-underline@3.23.5
+ - @tiptap/extensions@3.23.5
+ - @tiptap/extension-list-item@3.23.5
+ - @tiptap/extension-list-keymap@3.23.5
+ - @tiptap/extension-bullet-list@3.23.5
+ - @tiptap/extension-ordered-list@3.23.5
+ - @tiptap/extension-dropcursor@3.23.5
+ - @tiptap/extension-gapcursor@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/starter-kit/package.json b/packages/starter-kit/package.json
index 4f86889cdb..34feae7ddd 100644
--- a/packages/starter-kit/package.json
+++ b/packages/starter-kit/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/starter-kit",
"description": "starter kit for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/static-renderer/CHANGELOG.md b/packages/static-renderer/CHANGELOG.md
index 554655fe39..a08329afc2 100644
--- a/packages/static-renderer/CHANGELOG.md
+++ b/packages/static-renderer/CHANGELOG.md
@@ -1,5 +1,14 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/static-renderer/package.json b/packages/static-renderer/package.json
index 959b20fbd9..a02c20418a 100644
--- a/packages/static-renderer/package.json
+++ b/packages/static-renderer/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/static-renderer",
"description": "statically render Tiptap JSON",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/suggestion/CHANGELOG.md b/packages/suggestion/CHANGELOG.md
index 7157905fb7..442801f181 100644
--- a/packages/suggestion/CHANGELOG.md
+++ b/packages/suggestion/CHANGELOG.md
@@ -1,5 +1,14 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/suggestion/package.json b/packages/suggestion/package.json
index 3efa125867..6bbeb6ea52 100644
--- a/packages/suggestion/package.json
+++ b/packages/suggestion/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/suggestion",
"description": "suggestion plugin for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/vue-2/CHANGELOG.md b/packages/vue-2/CHANGELOG.md
index 3a0e0b1034..d2785e2f31 100644
--- a/packages/vue-2/CHANGELOG.md
+++ b/packages/vue-2/CHANGELOG.md
@@ -1,5 +1,22 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- 95e138c: fix(nodeview): eliminate unnecessary re-renders, add opt-in position tracking
+
+ NodeViews no longer re-render when decorations or position change without
+ content changes. Added `trackNodeViewPosition` option — when enabled, the
+ component re-renders on every position shift so calls to `getPos()` stay
+ current in render output. Removed the internal `nodeViewPositionRegistry`.
+ Added shallow prop comparison in `ReactRenderer.updateProps()`.
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/vue-2/package.json b/packages/vue-2/package.json
index 111a5dda7e..08a6ca8754 100644
--- a/packages/vue-2/package.json
+++ b/packages/vue-2/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/vue-2",
"description": "Vue components for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
diff --git a/packages/vue-3/CHANGELOG.md b/packages/vue-3/CHANGELOG.md
index 202081a25d..60f8efabca 100644
--- a/packages/vue-3/CHANGELOG.md
+++ b/packages/vue-3/CHANGELOG.md
@@ -1,5 +1,22 @@
# Change Log
+## 3.23.5
+
+### Patch Changes
+
+- 95e138c: fix(nodeview): eliminate unnecessary re-renders, add opt-in position tracking
+
+ NodeViews no longer re-render when decorations or position change without
+ content changes. Added `trackNodeViewPosition` option — when enabled, the
+ component re-renders on every position shift so calls to `getPos()` stay
+ current in render output. Removed the internal `nodeViewPositionRegistry`.
+ Added shallow prop comparison in `ReactRenderer.updateProps()`.
+
+- Updated dependencies [835caf5]
+- Updated dependencies [95e138c]
+ - @tiptap/core@3.23.5
+ - @tiptap/pm@3.23.5
+
## 3.23.4
### Patch Changes
diff --git a/packages/vue-3/package.json b/packages/vue-3/package.json
index 1828604ad9..d5de2b5e3b 100644
--- a/packages/vue-3/package.json
+++ b/packages/vue-3/package.json
@@ -1,7 +1,7 @@
{
"name": "@tiptap/vue-3",
"description": "Vue components for tiptap",
- "version": "3.23.4",
+ "version": "3.23.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",