React integration
2.2 React Integration & SSR Handling
When to Use
You're integrating Tiptap into a React or Next.js application.
Pattern
'use client' // Next.js App Router
import { useEditor, EditorContent } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
function Editor() {
const editor = useEditor({
extensions: [StarterKit],
content: '<p>Hello World</p>',
immediatelyRender: false, // CRITICAL for SSR
shouldRerenderOnTransaction: false, // Performance optimization
})
return <EditorContent editor={editor} />
}
Common Mistakes
- Omitting
'use client'directive → SSR error in Next.js App Router - Not setting
immediatelyRender: false→ Hydration mismatch errors - Using EditorProvider AND useEditor together → They're mutually exclusive; EditorProvider wraps useEditor
- Rendering editor in same component as unrelated state → Every state change re-renders editor; isolate in separate component
- Re-creating editor on every render → useEditor already memoizes; don't wrap in useMemo
- Setting
shouldRerenderOnTransaction: true→ Editor re-renders on every keystroke; useuseEditorStateinstead
Decision Points
| Scenario | Pattern | Why |
|---|---|---|
| Next.js App Router | 'use client' + immediatelyRender: false |
Prevents SSR execution |
| Next.js Pages Router | Dynamic import with ssr: false |
Ensures client-only rendering |
| Performance-critical UI | shouldRerenderOnTransaction: false + useEditorState |
Prevents unnecessary re-renders |
| Multi-editor instances | Separate components per editor | Prevents state interference |
See Also
- → 13.1 Next.js Setup | App Router patterns
- → 17.1 React Performance | Optimization techniques
- Reference: https://tiptap.dev/docs/editor/getting-started/install/react