Overview
The deleteWordBackward inputType is triggered when the user presses Ctrl/Cmd + Backspace. The browser deletes the word before the cursor position (backward word deletion).
Basic Behavior
Scenario: Cursor in middle of word
Before (Cursor at position 8)
After Ctrl/Cmd + Backspace
Scenario: Cursor at word boundary
Before (Cursor after "Hello")
After Ctrl/Cmd + Backspace
Word Boundary Detection
Browsers determine word boundaries differently:
- Whitespace characters (spaces, tabs, newlines) typically mark word boundaries
- Punctuation may or may not be included in word deletion depending on browser
- CJK (Chinese, Japanese, Korean) characters may be treated as individual words or grouped differently
- Behavior may vary between browsers and languages
Browser-Specific Behavior
Chrome/Edge
- Deletes word including trailing space
- Word boundary detection based on Unicode word boundaries
Firefox
- Similar behavior to Chrome
- May handle punctuation differently
Safari
- Word boundary detection may differ
- May include or exclude trailing spaces differently
IME Composition + deleteWordBackward
⚠️ Critical Issue
During IME composition, pressing Ctrl/Cmd + Backspace may cancel the composition or delete more than expected. The behavior varies significantly between browsers and IME implementations.
See: deleteContentBackward for similar issues with regular Backspace.
Editor-Specific Handling
Different editor frameworks handle word-level deletion differently. Here's how major editors implement deleteWordBackward:
Word Backward Deletion
Slate uses Transforms.delete() with word unit:
import { Editor, Transforms } from 'slate';
element.addEventListener('beforeinput', (e) => {
if (e.inputType === 'deleteWordBackward') {
e.preventDefault();
const { selection } = editor;
if (selection) {
// Delete word backward
Transforms.delete(editor, { reverse: true, unit: 'word' });
}
}
});
- Transforms.delete: Uses
unit: 'word'withreverse: true. - Word detection: Slate determines word boundaries based on whitespace and punctuation.
Word Backward Deletion
ProseMirror uses deleteSelection with word boundary detection:
import { deleteSelection } from 'prosemirror-commands';
view.dom.addEventListener('beforeinput', (e) => {
if (e.inputType === 'deleteWordBackward') {
e.preventDefault();
const { state, dispatch } = view;
// Extend selection backward to word boundary
const { $from } = state.selection;
const wordStart = $from.startOfWordback($from);
if (wordStart !== null) {
const tr = state.tr.delete(wordStart.pos, $from.pos);
dispatch(tr);
}
}
});
- Word boundary detection: Uses
startOfWordback()to find word start. - Transaction-based: Creates transaction to delete word range.
Word Backward Deletion
Draft.js uses SelectionState to find word boundaries:
import { EditorState, Modifier } from 'draft-js';
function handleDeleteWordBackward(editorState) {
const contentState = editorState.getCurrentContent();
const selection = editorState.getSelection();
// Find word start
const block = contentState.getBlockForKey(selection.getStartKey());
const text = block.getText();
const offset = selection.getStartOffset();
// Find word boundary (simplified - real implementation would be more complex)
let wordStart = offset;
while (wordStart > 0 && /S/.test(text[wordStart - 1])) {
wordStart--;
}
// Create new selection from word start to cursor
const newSelection = selection.merge({
anchorOffset: wordStart,
focusOffset: offset,
});
// Delete selection
const newContentState = Modifier.removeRange(
contentState,
newSelection,
'backward'
);
return EditorState.push(
editorState,
newContentState,
'remove-range'
);
}
- Word boundary detection: Manually finds word start by scanning backward for whitespace.
- Selection extension: Extends selection to word boundary before deleting.