diff --git a/docs/src/demos/Experiments/TrailingNode/index.vue b/docs/src/demos/Experiments/TrailingNode/index.vue
new file mode 100644
index 00000000..b818885a
--- /dev/null
+++ b/docs/src/demos/Experiments/TrailingNode/index.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
diff --git a/docs/src/demos/Experiments/TrailingNode/trailing-node.ts b/docs/src/demos/Experiments/TrailingNode/trailing-node.ts
new file mode 100644
index 00000000..e2c47c09
--- /dev/null
+++ b/docs/src/demos/Experiments/TrailingNode/trailing-node.ts
@@ -0,0 +1,68 @@
+import { Extension } from '@tiptap/core'
+import { PluginKey, Plugin } from 'prosemirror-state'
+
+// @ts-ignore
+function nodeEqualsType({ types, node }) {
+ return (Array.isArray(types) && types.includes(node.type)) || node.type === types
+}
+
+/**
+ * Extension based on:
+ * - https://github.com/ueberdosis/tiptap/blob/v1/packages/tiptap-extensions/src/extensions/TrailingNode.js
+ * - https://github.com/remirror/remirror/blob/e0f1bec4a1e8073ce8f5500d62193e52321155b9/packages/prosemirror-trailing-node/src/trailing-node-plugin.ts
+ */
+
+export interface TrailingNodeOptions {
+ node: string,
+ notAfter: string[],
+}
+
+export const TrailingNode = Extension.create({
+ name: 'trailingNode',
+
+ defaultOptions: {
+ node: 'paragraph',
+ notAfter: [
+ 'paragraph',
+ ],
+ },
+
+ addProseMirrorPlugins() {
+ const plugin = new PluginKey(this.name)
+ const disabledNodes = Object.entries(this.editor.schema.nodes)
+ .map(([, value]) => value)
+ .filter(node => this.options.notAfter.includes(node.name))
+
+ return [
+ new Plugin({
+ key: plugin,
+ appendTransaction: (_, __, state) => {
+ const { doc, tr, schema } = state
+ const shouldInsertNodeAtEnd = plugin.getState(state)
+ const endPosition = doc.content.size
+ const type = schema.nodes[this.options.node]
+
+ if (!shouldInsertNodeAtEnd) {
+ return
+ }
+
+ return tr.insert(endPosition, type.create())
+ },
+ state: {
+ init: (_, state) => {
+ const lastNode = state.tr.doc.lastChild
+ return !nodeEqualsType({ node: lastNode, types: disabledNodes })
+ },
+ apply: (tr, value) => {
+ if (!tr.docChanged) {
+ return value
+ }
+
+ const lastNode = tr.doc.lastChild
+ return !nodeEqualsType({ node: lastNode, types: disabledNodes })
+ },
+ },
+ }),
+ ]
+ },
+})
diff --git a/docs/src/docPages/experiments.md b/docs/src/docPages/experiments.md
index 33957c71..41e29d5d 100644
--- a/docs/src/docPages/experiments.md
+++ b/docs/src/docPages/experiments.md
@@ -10,3 +10,4 @@ Congratulations! You’ve found our playground with a list of experiments. Be aw
* [@tiptap/extension-toggle-list?](/experiments/details)
* [@tiptap/extension-collaboration-annotation](/experiments/collaboration-annotation)
* [@tiptap/extension-word-break](/experiments/word-break)
+* [@tiptap/extension-trailing-node](/experiments/trailing-node)
diff --git a/docs/src/docPages/experiments/trailing-node.md b/docs/src/docPages/experiments/trailing-node.md
new file mode 100644
index 00000000..36c25ea5
--- /dev/null
+++ b/docs/src/docPages/experiments/trailing-node.md
@@ -0,0 +1,5 @@
+# Trailing node
+
+⚠️ Experiment
+
+