Add span Extension

Hello everyone,

Im using a TipTap Editor in my application which is based on Prose Mirror. I want to create a extension that is inserting a span with the content {{}} and also adds a id to the span-tag. Now im forcing a problem which i try to fix for hours. This is my Code:

import { Extension } from '@tiptap/core'
import { Schema } from 'prosemirror-model'
import { schema as basicSchema } from 'prosemirror-schema-basic'
import { NodeSelection } from 'prosemirror-state'

const nodes = {
  text: {},
  doc: {},
  span: {
    attrs: {
      id: { default: null }
    content: 'text*',
    inline: true,
    group: 'inline',
    draggable: true,
    parseDOM: [
        tag: 'span[id]',
        getAttrs: node => (
          { id: node.getAttribute('id') }
    toDOM(node) {
      return ['span', { id: }, 0]

export const UserPlaceholder = Extension.create({
  name: 'userPlaceholder',

  addCommands() {
    const mySchema = new Schema({
      marks: basicSchema.spec.marks

    return {
      createPlaceholder: attrs => ({
      }) => {
        const {
        } = tr.selection

        const nodeSpec = mySchema.nodes['span']
        const node = nodeSpec.create(attrs, mySchema.text('{{}}', null))

        if (from !== to) {
          const transaction = tr.replaceWith(from, to, node)
        } else {
          const sel = NodeSelection.create(tr.doc, from + 1)
          const transaction = tr.setSelection(sel).replaceWith(from, to, node)

        return true

This is the Error i get when i execute the command on a empty editor view:

Uncaught TypeError: Cannot read properties of null (reading ‘nodeSize’) at new NodeSelection (index.js:342:57) at NodeSelection.create (index.js:375:16) at PlaceholderExtension.js:272:39 at Object.chainedCommand [as createPlaceholder] (CommandManager.ts:86:45) at Proxy.addSpanTag (TiptapEditor.vue:109:28) at _createVNode.onClick._cache.._cache. (TiptapEditor.vue:21:21) at callWithErrorHandling (runtime-core.esm-bundler.js:157:22) at callWithAsyncErrorHandling (runtime-core.esm-bundler.js:166:21) at emit$1 (runtime-core.esm-bundler.js:714:9) at runtime-core.esm-bundler.js:7430:53

when i add some blanc lines before i execute the command nothing happens. The node i created which i want to replace with my span node didn´t change and the editor state didn´t change.

This is a message where mapping is used to determine the appropriate selection position: tr.replaceWith gets wrong selection mapping (codeblocks) · Issue #645 · ProseMirror/prosemirror · GitHub where NodeSelection.findFrom is used instead.

Its possible this may work - I think you are not pointing to the beginning of the newly inserted Node - and if I recall correctly, that is the error message you’d receive but not 100% sure.

This also possibly relevant: Selecting a Block-Level Node after Insertion - #5 by amxmln

But perhaps @marijn could confirm and I think he’d know immediately.