Tiptap best practices and tips
This guide covers best practices and common pitfalls to avoid when working with Tiptap and Liveblocks.
Always include StarterKit or Doc & Paragraph extensions
The Tiptap StarterKit extension is required for Tiptap to function properly. It provides essential node types that every Tiptap editor needs, specifically the Doc and Paragraph nodes. Alternatively you can include only the Doc and Paragraph extensions.
Why StarterKit is required
Tiptap documents must have a root Doc node and at least one Paragraph node to maintain a valid document structure. Without these core nodes, the editor will not work correctly and synchronization will fail.
What StarterKit includes
In addition to the required Doc and Paragraph nodes, StarterKit also includes commonly used extensions like:
- Text formatting (Bold, Italic, Strike, Code)
- Block types (Heading, Blockquote, CodeBlock, BulletList, OrderedList, ListItem)
- Horizontal rule and hard break
- History (undo/redo) (This must be disabled to work with Liveblocks)
If you need more control over which extensions are included, you can configure StarterKit to disable specific extensions:
However, you should never disable the doc or paragraph options, as these are required for the editor to function.
Disable server-side rendering with immediatelyRender: false
When using Tiptap with server-side rendering (SSR) frameworks like Next.js, you should always set immediatelyRender: false in your useEditor hook. Tiptap should never be rendered on the server.
Why disable server-side rendering?
Tiptap is a client-side editor that relies on browser APIs and the DOM. When rendered on the server, it can cause:
- Hydration mismatches between server and client
- Errors related to missing browser APIs
How to disable server-side rendering
Set immediatelyRender: false in your useEditor configuration:
This ensures that Tiptap is only rendered on the client side, avoiding any server-side rendering issues.
Enable content validation
Tiptap has a schema that defines the structure of your document. By default, Tiptap does not validate content against this schema. When invalid content is present, it will silently break synchronization without any error messages.
This can happen when:
- Extensions are added or removed from the editor
- The schema changes between different versions of your application
- Users collaborate on documents with different editor configurations
How to enable content validation
Always enable content validation by setting enableContentCheck: true and implementing an onContentError handler:
This ensures that:
- Invalid content is detected early
- Collaboration is disabled to prevent data corruption
- The editor is made read-only to prevent further changes
- The issue is logged for debugging
- Users are notified of the problem
Use initialContent instead of content
When setting default content for your Tiptap editor, always use initialContent on useLiveblocksExtension instead of content on useEditor. Using content will cause the content to be appended to the document every time the page loads or the component re-renders.
The problem with content
The content option in Tiptap sets the editor content every time the editor is initialized. When using Liveblocks, this means the content will be added to the existing document rather than replacing it, causing duplication:
Use initialContent instead
The initialContent option sets a flag internally and only sets the content the very first time the document is empty. This prevents duplication:
Support multiple editors with the field option
If you want to display multiple Tiptap editors on the same page, use the field option with a unique identifier for each editor. This ensures that each editor synchronizes to its own section of the Yjs document.
Without the field option, both editors would synchronize to the same location in the document, causing conflicts and data loss.
Never use extensions with binary data
Never use Tiptap extensions that store binary data (such as base64-encoded images) directly in the document. Binary data will be synchronized across all clients and can fill up your Liveblocks room extremely quickly, leading to:
- Increased bandwidth usage
- Slower synchronization
- Higher storage costs
- Potential rate limiting
Common pitfall: Image extension
The official Tiptap Image extension has an allowBase64 option. This option is defaulted to false, and it should never be set to true.
Recommended approach
Instead of storing images as base64 in the document:
- Upload images to a file storage service (e.g., AWS S3, Cloudflare R2, Vercel Blob)
- Store only the URL in the document
- Reference the URL in your image nodes
Prevent users from losing unsaved changes
To prevent users from accidentally losing their work when closing the browser tab or navigating away, enable the preventUnsavedChanges option:
This will display a browser confirmation dialog when users try to leave the page with unsaved changes, helping prevent accidental data loss. Learn more.