Overview
The insertReplacementText inputType is triggered when text is replaced by auto-complete, predictive text, or suggestion features. This is particularly common on mobile devices with smart keyboards that offer word suggestions and auto-complete.
Basic Behavior
Scenario: Auto-complete suggestion selected
Before (User typing "hel")
After selecting suggestion "hello"
Mobile-Specific Behavior
⚠️ Android Samsung Keyboard
Android + Samsung Keyboard: When text prediction/suggestion features are enabled, selecting suggested text may cause unexpected behavior:
insertReplacementTextmay fire with the full suggested phrase- Multiple
inputevents may fire for a single suggestion selection - The
beforeinputevent may not fire before replacement - Suggested text may replace more content than expected (entire words instead of partial words)
- Event timing may differ from manual typing, making it difficult to track changes accurately
Impact: Text replacement can interfere with custom editing logic, undo/redo stacks, and change tracking systems.
iOS Auto-complete
- iOS keyboards may use
insertReplacementTextfor QuickType suggestions - Behavior is generally more predictable than Android keyboards
- May replace partial words or entire words depending on context
Browser Support
Chrome/Edge (Desktop)
- May use
insertReplacementTextfor browser autocomplete features - Less common than on mobile devices
Mobile Browsers
- More commonly used for keyboard suggestions and auto-complete
- Behavior varies significantly between keyboard apps and browsers
- May trigger multiple events for a single replacement
Handling insertReplacementText
Best Practices
- Monitor both
beforeinputandinputevents to catch all text replacements - Compare DOM state before and after events to detect bulk text replacements
- Use
e.dataproperty to identify replaced text vs manual typing - Consider disabling text prediction via
autocomplete="off"orspellcheck="false"if it interferes with your use case - Handle
insertReplacementTextsimilarly toinsertText, but be aware that it may replace existing content
Editor-Specific Handling
Different editor frameworks handle text replacement similarly to text insertion. Here's how major editors implement insertReplacementText:
Text Replacement Handling
Slate handles replacement by deleting old text and inserting new text:
import { Editor, Transforms } from 'slate';
element.addEventListener('beforeinput', (e) => {
if (e.inputType === 'insertReplacementText' && e.data) {
e.preventDefault();
const { selection } = editor;
if (selection && !selection.isCollapsed) {
// Delete selected text first
Transforms.delete(editor);
}
// Insert replacement text
Transforms.insertText(editor, e.data);
}
});
- Two-step process: Deletes old text, then inserts replacement text.
- Selection handling: Handles both collapsed and non-collapsed selections.
Text Replacement Handling
ProseMirror uses replaceSelection to handle replacement:
import { insertText } from 'prosemirror-commands';
view.dom.addEventListener('beforeinput', (e) => {
if (e.inputType === 'insertReplacementText' && e.data) {
e.preventDefault();
const { state, dispatch } = view;
// Replace selection with new text
if (insertText(state, e.data, state.selection.$from.marks(), dispatch)) {
// Handled
}
}
});
- insertText command: Automatically replaces selection with new text.
- Mark preservation: Current marks are applied to replacement text.
Text Replacement Handling
Draft.js uses Modifier.replaceText to handle replacement:
import { EditorState, Modifier } from 'draft-js';
function handleReplacementText(editorState, text) {
const contentState = editorState.getCurrentContent();
const selection = editorState.getSelection();
// Replace selection with new text
const newContentState = Modifier.replaceText(
contentState,
selection,
text,
editorState.getCurrentInlineStyle()
);
return EditorState.push(
editorState,
newContentState,
'insert-characters'
);
}
element.addEventListener('beforeinput', (e) => {
if (e.inputType === 'insertReplacementText' && e.data) {
e.preventDefault();
const newState = handleReplacementText(editorState, e.data);
setEditorState(newState);
}
});
- Modifier.replaceText: Replaces selection with new text in one operation.
- Style preservation: Current inline styles are applied to replacement text.