> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/ueberdosis/tiptap/llms.txt
> Use this file to discover all available pages before exploring further.

# useEditor

> React hook for creating and managing a Tiptap editor instance

## Overview

The `useEditor` hook is the primary way to create and manage a Tiptap editor instance in React applications. It handles the editor lifecycle, including creation, updates, and cleanup.

## Type Signature

```typescript theme={null}
function useEditor(
  options: UseEditorOptions,
  deps?: DependencyList
): Editor | null
```

## Parameters

<ParamField path="options" type="UseEditorOptions" required>
  Configuration options for the editor instance. Extends `Partial<EditorOptions>` from `@tiptap/core`.

  <Expandable title="properties">
    <ParamField path="extensions" type="Extension[]">
      Array of Tiptap extensions to use in the editor.
    </ParamField>

    <ParamField path="content" type="Content">
      Initial content for the editor. Can be HTML, JSON, or a ProseMirror document.
    </ParamField>

    <ParamField path="editable" type="boolean" default="true">
      Whether the editor should be editable.
    </ParamField>

    <ParamField path="autofocus" type="boolean | 'start' | 'end' | number" default="false">
      Automatically focus the editor on mount. Can be `true`, `false`, `'start'`, `'end'`, or a specific position.
    </ParamField>

    <ParamField path="immediatelyRender" type="boolean" default="true">
      Whether to render the editor on the first render. Set to `false` for server-side rendering to avoid hydration mismatches.
    </ParamField>

    <ParamField path="shouldRerenderOnTransaction" type="boolean" default="false">
      Whether to re-render the editor on each transaction. This is legacy behavior that will be removed in future versions.
    </ParamField>

    <ParamField path="onCreate" type="(props: EditorEvents['create']) => void">
      Callback function called when the editor is created.
    </ParamField>

    <ParamField path="onUpdate" type="(props: EditorEvents['update']) => void">
      Callback function called when the editor content changes.
    </ParamField>

    <ParamField path="onTransaction" type="(props: EditorEvents['transaction']) => void">
      Callback function called on every transaction.
    </ParamField>

    <ParamField path="onFocus" type="(props: EditorEvents['focus']) => void">
      Callback function called when the editor receives focus.
    </ParamField>

    <ParamField path="onBlur" type="(props: EditorEvents['blur']) => void">
      Callback function called when the editor loses focus.
    </ParamField>

    <ParamField path="onSelectionUpdate" type="(props: EditorEvents['selectionUpdate']) => void">
      Callback function called when the selection changes.
    </ParamField>

    <ParamField path="onBeforeCreate" type="(props: EditorEvents['beforeCreate']) => void">
      Callback function called before the editor is created.
    </ParamField>

    <ParamField path="onDestroy" type="() => void">
      Callback function called when the editor is destroyed.
    </ParamField>

    <ParamField path="onContentError" type="(props: EditorEvents['contentError']) => void">
      Callback function called when there's an error with the content.
    </ParamField>

    <ParamField path="onDrop" type="(props: EditorEvents['drop']) => void">
      Callback function called when content is dropped into the editor.
    </ParamField>

    <ParamField path="onPaste" type="(props: EditorEvents['paste']) => void">
      Callback function called when content is pasted into the editor.
    </ParamField>

    <ParamField path="onDelete" type="(props: EditorEvents['delete']) => void">
      Callback function called when content is deleted.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField path="deps" type="DependencyList" default="[]">
  Optional React dependency array. When dependencies change, the editor instance will be destroyed and recreated.
</ParamField>

## Return Value

Returns an `Editor` instance or `null`. The return value can be `null` when:

* The editor has not been initialized yet
* `immediatelyRender` is set to `false` and the editor hasn't mounted
* Server-side rendering is detected

## Usage Examples

### Basic Usage

```tsx theme={null}
import { useEditor, EditorContent } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'

function MyEditor() {
  const editor = useEditor({
    extensions: [StarterKit],
    content: '<p>Hello World!</p>',
  })

  return <EditorContent editor={editor} />
}
```

### With Event Handlers

```tsx theme={null}
import { useEditor, EditorContent } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import { useState } from 'react'

function MyEditor() {
  const [status, setStatus] = useState('initializing')

  const editor = useEditor({
    extensions: [StarterKit],
    content: '<p>Hello World!</p>',
    onCreate: () => {
      setStatus('created')
    },
    onUpdate: ({ editor }) => {
      console.log('Content updated:', editor.getHTML())
    },
    onFocus: () => {
      setStatus('focused')
    },
    onBlur: () => {
      setStatus('blurred')
    },
  })

  return (
    <div>
      <p>Editor status: {status}</p>
      <EditorContent editor={editor} />
    </div>
  )
}
```

### With Dependencies

```tsx theme={null}
import { useEditor, EditorContent } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'

function MyEditor({ initialContent }: { initialContent: string }) {
  const editor = useEditor({
    extensions: [StarterKit],
    content: initialContent,
  }, [initialContent]) // Recreate editor when initialContent changes

  return <EditorContent editor={editor} />
}
```

### Server-Side Rendering

```tsx theme={null}
import { useEditor, EditorContent } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'

function MyEditor() {
  const editor = useEditor({
    extensions: [StarterKit],
    content: '<p>Hello World!</p>',
    immediatelyRender: false, // Required for SSR
  })

  if (!editor) {
    return <div>Loading editor...</div>
  }

  return <EditorContent editor={editor} />
}
```

### Controlled Editor

```tsx theme={null}
import { useEditor, EditorContent } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import { useEffect, useState } from 'react'

function MyEditor() {
  const [content, setContent] = useState('<p>Hello World!</p>')

  const editor = useEditor({
    extensions: [StarterKit],
    content,
    onUpdate: ({ editor }) => {
      setContent(editor.getHTML())
    },
  })

  // Update editor when external content changes
  useEffect(() => {
    if (editor && editor.getHTML() !== content) {
      editor.commands.setContent(content)
    }
  }, [content, editor])

  return (
    <div>
      <EditorContent editor={editor} />
      <textarea
        value={content}
        onChange={(e) => setContent(e.target.value)}
      />
    </div>
  )
}
```

## Important Notes

<Warning>
  When using server-side rendering (SSR) with frameworks like Next.js, you must set `immediatelyRender: false` to avoid hydration mismatches. In development mode, Tiptap will throw an error if SSR is detected without this option.
</Warning>

<Note>
  The `shouldRerenderOnTransaction` option is legacy behavior. For better performance, leave it as `false` (default) and use the `useEditorState` hook for reactive state updates instead.
</Note>

<Tip>
  Use the `deps` array sparingly. Only include dependencies when you actually need to recreate the editor instance. For most use cases, updating editor options or content through commands is more efficient.
</Tip>

## Related

* [EditorContent](/api/react/editor-content) - Component for rendering the editor
* [useEditorState](https://tiptap.dev/docs/editor/api/hooks/use-editor-state) - Hook for reactive editor state
* [Editor](https://tiptap.dev/docs/editor/api/editor) - Core editor API reference
