Resolved: Use InputRule to replace Block

Read Comment I have a node, Container, that is designed to wrap other nodes ( paragraphs, headings etc). Here is a snippet of the schema:

    return {
      content: "block",
      draggable: true,
      toDOM: () => ["div", { "data-type": "drag_item" }, 0],
      parseDOM: [
          tag: `[data-type="drag_item"]`

As you can see, it accepts any node that subscribes to the block group as content. My goal was to use ReplaceSelectionWith to change the content node from say a paragraph (which subscribes to the block group) to a heading (which also is apart of the block group) using an InputRule ( #, > etc). Instead of changing the content of the Container node, it creates another container with the intended nodeType. Here is how I approach the transaction change (I use a wrapper for the InputRule for modularity) :

export default function (regexp: RegExp, type, getAttrs) {
    return new InputRule(regexp, (state, match, start, end) => {
        const attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs
        const { tr } = state
        if (match[0]){

        return tr

To reiterate the outcome, this transaction creates another block with the intended content, but does not replace it as intended. How do I remedy this situation?

Was able to get it to work by changing replaceSelectionWith with setBlockType, however, the input rule expression didn’t go away. (> still in text)

I was able to fully remedy this by using replaceWith

  1. Trigger Input Rule
  2. In InputRule method, get doc and find all nodes within start,end range.
  3. get the start position of the node and node size
  4. tr.replaceWIth(rangeStart, rangeEnd, type.create()) 5 return tr