insertLineBreak

How insertLineBreak inputType creates line breaks and varies across browsers.

Overview

The insertLineBreak inputType is triggered when the user presses Shift + Enter. The browser inserts a <br> element instead of creating a new paragraph.

Basic Behavior

Scenario: Cursor in middle of paragraph

Before (Cursor at position 5)

HTML:
<p>Hello|world</p>

After Shift + Enter

HTML:
<p>Hello|<br>world</p>
Inserts <br> within same paragraph

Difference from insertParagraph

insertLineBreak (Shift + Enter)

  • Inserts <br> element
  • Stays within the same paragraph/block
  • Creates a line break without creating a new block element

insertParagraph (Enter)

  • Creates a new <p> or <div> element
  • Splits the current paragraph into two separate blocks
  • Browser-dependent structure (see insertParagraph)

IME Composition + insertLineBreak

⚠️ Critical Issue

During IME composition, pressing Shift + Enter may cancel the composition or commit it partially, similar to insertParagraph.

See: insertParagraph for detailed information about composition cancellation.

Editor-Specific Handling

Different editor frameworks handle line breaks differently from paragraph breaks. Here's how major editors implement insertLineBreak:

Slate.js

Line Break Insertion

Slate uses Transforms.insertNodes() to insert a line break node:

    import { Editor, Transforms, Element } from 'slate';

element.addEventListener('beforeinput', (e) => {
  if (e.inputType === 'insertLineBreak') {
    e.preventDefault();
    
    // Insert a line break node (not a new block)
    Transforms.insertNodes(editor, {
      type: 'line-break',
      children: [{ text: '' }],
    });
    
    // Or insert a soft break within the current block
    // depending on your schema design
  }
});
  
  • Node insertion: Inserts a line break node instead of splitting blocks.
  • Block preservation: Keeps content within the same block element.
  • Schema-dependent: Line break representation depends on your Slate schema design.
ProseMirror

Line Break Insertion

ProseMirror uses insertHardBreak command:

    import { insertHardBreak } from 'prosemirror-commands';

view.dom.addEventListener('beforeinput', (e) => {
  if (e.inputType === 'insertLineBreak') {
    e.preventDefault();
    const { state, dispatch } = view;
    if (insertHardBreak(state, dispatch)) {
      // Handled
    }
  }
});
  
  • insertHardBreak command: Inserts a hard break node (<br> equivalent).
  • Block preservation: Stays within the current block, unlike splitBlock.
Draft.js

Line Break Insertion

Draft.js uses Modifier.insertText() with newline character:

    import { EditorState, Modifier } from 'draft-js';

function handleInsertLineBreak(editorState) {
  const contentState = editorState.getCurrentContent();
  const selection = editorState.getSelection();
  
  // Insert newline character (rendered as <br>)
  const newContentState = Modifier.insertText(
    contentState,
    selection,
    '\n',
    editorState.getCurrentInlineStyle()
  );
  
  return EditorState.push(
    editorState,
    newContentState,
    'insert-characters'
  );
}

element.addEventListener('beforeinput', (e) => {
  if (e.inputType === 'insertLineBreak') {
    e.preventDefault();
    const newState = handleInsertLineBreak(editorState);
    setEditorState(newState);
  }
});
  
  • Newline character: Inserts \n which is rendered as <br>.
  • Block preservation: Stays within the same ContentBlock.

Related resources