Cursor jumps to next line when inserting node

Hi there, I’m new to ProseMirror so I’m sure this is a beginner mistake.

We’ve implemented a mention-similar feature for a few different things that allows users to type a character, like “#”, and get a list of (in this case) previously used tags.

This is working well, but when we’re inserting the resulting selection, it gets inserted correctly as inline (as far as I can tell), but the cursor jumps to the next line. However, if you then just type, the text appears correctly inline. This behavior is the same regardless of browser and platform as far as I can tell.

See here:

CleanShot 2022-12-02 at 12.44.07

This is how the tag is defined:

let sirapTag = {
	attrs: {
		tag_id: -1,
	inline: true,
	group: 'inline',
	draggable: true,

	parseDOM: [{
		tag: 'span[class=sirapTag]',
		priority: 1000,
		getAttrs(dom) {
			return {
				tag_id: +(dom.getAttribute('data-tag-id')),
	toDOM(node) {
		let {tag_id} = node.attrs;
		let tag = [here we're getting the right tag ID from our db]
		if( tag == undefined )
			return '';

		return [
				class: "sirapTag",
				'data-tag-id': tag_id,

The sirapTag class above is defined (using Tailwind) as:

	.sirapTag::before {
		@apply [content:"#"] font-normal text-sm text-gray-400 dark:text-gray-500;
	.sirapTag {
		@apply inline px-2 py-px text-sm rounded-full font-semibold bg-midnight/7 dark:bg-gray-100/7 text-gray-500 dark:text-gray-400;

Having this as inline or inline-block (i.e. display: inline; or display: inline-block;) seems to make no difference.

What are we doing wrong? It’s driving me nuts :grinning:

I’m not sure what’s happening. Possibly you’re not stopping the enter event and it’s being handled twice? Or you don’t put the cursor in the right position after the insertion?

Thanks @marijn - after some more digging around we found that this seems to be caused by the addition of an img and a br tag added by addHackNode()

See this issue discussed here: What is addHackNode? but unsure what the solution was?

The only solution we’ve found is to use CSS to prevent the separator class from breaking the line and using zero-width spaces ::before and ::after. Not sure if this is the best / preferred way to do it but seems to work. Is this documented somewhere? Feels a bit hacky.

img.ProseMirror-separator {
    display: inline !important;
    border: none !important;
    margin: 0 !important;
/* This is tailwind */
.sirapIssue::after {
	@apply [font-size:0px] [content:"_"];