Skip to main content
Lexical provides React components for rendering editable content and handling errors.

ContentEditable

The editable content area where users interact with the editor.
import { ContentEditable } from '@lexical/react/LexicalContentEditable';

function Editor() {
  return (
    <ContentEditable
      className="editor-input"
      aria-placeholder="Enter some text..."
      placeholder={
        <div className="editor-placeholder">
          Enter some text...
        </div>
      }
    />
  );
}

Props

Extends all standard HTML <div> attributes except placeholder.
className
string
CSS class name for styling the editable area.
aria-label
string
Accessible label for screen readers.
aria-placeholder
string
Accessible placeholder text. Required if using the placeholder prop.
placeholder
JSX.Element | ((isEditable: boolean) => JSX.Element | null) | null
Placeholder content displayed when the editor is empty. Can be a static element or a function that receives the editable state.
role
string
ARIA role. Defaults to "textbox".
spellCheck
boolean
Enable browser spell checking. Defaults to true.
tabIndex
number
Tab order for keyboard navigation.
ariaActiveDescendant
string
ARIA active descendant for accessibility.
ariaAutoComplete
'none' | 'inline' | 'list' | 'both'
ARIA autocomplete attribute.
ariaControls
string
ARIA controls attribute.
ariaDescribedBy
string
ARIA described-by attribute.
ariaErrorMessage
string
ARIA error message attribute.
ariaExpanded
boolean
ARIA expanded state.
ariaInvalid
boolean
ARIA invalid state.
ariaLabelledBy
string
ARIA labelled-by attribute.
ariaMultiline
boolean
ARIA multiline attribute.
ariaOwns
string
ARIA owns attribute.
ariaRequired
boolean
ARIA required attribute.
autoCapitalize
string
HTML autocapitalize attribute for mobile devices.
data-testid
string
Test ID for testing frameworks.

Ref

The component forwards a ref to the underlying <div> element:
const editorRef = useRef<HTMLDivElement>(null);

<ContentEditable ref={editorRef} />

ContentEditableElement

Lower-level version of ContentEditable that requires passing the editor instance explicitly. Used internally by ContentEditable.
import { ContentEditableElement } from '@lexical/react/LexicalContentEditable';

function CustomEditable() {
  const [editor] = useLexicalComposerContext();

  return (
    <ContentEditableElement
      editor={editor}
      className="editor-input"
    />
  );
}

Props

Same as ContentEditable props, plus:
editor
LexicalEditor
required
The editor instance to attach to.

LexicalErrorBoundary

Error boundary component for catching and handling errors in decorators.
import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';

function Editor() {
  const handleError = (error: Error) => {
    console.error('Editor error:', error);
  };

  return (
    <LexicalComposer initialConfig={config}>
      <RichTextPlugin
        contentEditable={<ContentEditable />}
        placeholder={null}
        ErrorBoundary={LexicalErrorBoundary}
      />
    </LexicalComposer>
  );
}

Props

children
JSX.Element
required
Child elements to wrap with error boundary.
onError
(error: Error) => void
required
Callback invoked when an error is caught.

Behavior

When an error occurs, displays a red error message:
┌─────────────────────┐
│ An error was thrown.│
└─────────────────────┘

Advanced Components

LexicalTreeView

Development tool for visualizing the editor’s node tree.
import { TreeView } from '@lexical/react/LexicalTreeView';

function DebugEditor() {
  const [editor] = useLexicalComposerContext();

  return (
    <div>
      <ContentEditable />
      <TreeView
        editor={editor}
        treeTypeButtonClassName="tree-type-button"
        timeTravelButtonClassName="time-travel-button"
        timeTravelPanelButtonClassName="time-travel-panel-button"
        timeTravelPanelClassName="time-travel-panel"
        timeTravelPanelSliderClassName="time-travel-panel-slider"
        viewClassName="tree-view"
      />
    </div>
  );
}
Props: Class names for styling the tree view components.

DecoratorBlockNode

Base class for creating block-level decorator nodes. Not a React component, but a node class used with React.
import { DecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode';

class ImageNode extends DecoratorBlockNode {
  static getType() {
    return 'image';
  }

  decorate() {
    return <ImageComponent nodeKey={this.getKey()} />;
  }
}
See the Nodes API documentation for more details on creating custom nodes.

Styling Examples

Basic Editor Styling

.editor-input {
  min-height: 150px;
  resize: none;
  font-size: 15px;
  position: relative;
  tab-size: 1;
  outline: 0;
  padding: 15px 10px;
  caret-color: rgb(5, 5, 5);
}

.editor-placeholder {
  color: #999;
  overflow: hidden;
  position: absolute;
  text-overflow: ellipsis;
  top: 15px;
  left: 10px;
  font-size: 15px;
  user-select: none;
  display: inline-block;
  pointer-events: none;
}

Selected State

.editor-input:focus {
  outline: 2px solid rgb(60, 132, 244);
}

[contenteditable="false"] .editor-input {
  background-color: #f5f5f5;
}

With Placeholder Function

<ContentEditable
  aria-placeholder="Start typing..."
  placeholder={(isEditable) => (
    <div className="editor-placeholder">
      {isEditable ? 'Start typing...' : 'Read-only mode'}
    </div>
  )}
/>

Build docs developers (and LLMs) love