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
\nwhich is rendered as<br>. - Block preservation: Stays within the same ContentBlock.