insertReplacementText

How insertReplacementText inputType handles auto-complete and text replacement operations, especially on mobile devices.

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")

HTML:
<p>hel|</p>
Keyboard suggests "hello"

After selecting suggestion "hello"

HTML:
<p>hello|</p>
Partial text replaced with full suggestion

Mobile-Specific Behavior

⚠️ Android Samsung Keyboard

Android + Samsung Keyboard: When text prediction/suggestion features are enabled, selecting suggested text may cause unexpected behavior:

  • insertReplacementText may fire with the full suggested phrase
  • Multiple input events may fire for a single suggestion selection
  • The beforeinput event 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 insertReplacementText for 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 insertReplacementText for 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 beforeinput and input events to catch all text replacements
  • Compare DOM state before and after events to detect bulk text replacements
  • Use e.data property to identify replaced text vs manual typing
  • Consider disabling text prediction via autocomplete="off" or spellcheck="false" if it interferes with your use case
  • Handle insertReplacementText similarly to insertText, 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:

Slate.js

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.
ProseMirror

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.
Draft.js

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.

Related resources