Make your Lexical editor collaborative in minutes

Liveblocks enables you to add realtime syncing and multiplayer features to your Lexical editor with Yjs, a realtime data store designed for collaborative text editors.

Companies of all sizes and industries use Liveblocks

Yjs -
Supercharged Yjs developer experience

Liveblocks Yjs is a realtime sync engine designed for collaborative text editors such as Notion and Google Docs.

import { useRoom } from "../liveblocks.config";import * as Y from "yjs";import LiveblocksProvider from "@liveblocks/yjs";import {  $getRoot,  $createParagraphNode,  $createTextNode,  LexicalEditor,} from "lexical";import { LexicalComposer } from "@lexical/react/LexicalComposer";import { ContentEditable } from "@lexical/react/LexicalContentEditable";import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";import { CollaborationPlugin } from "@lexical/react/LexicalCollaborationPlugin";import LexicalErrorBoundary from "@lexical/react/LexicalErrorBoundary";import { Provider } from "@lexical/yjs";import styles from "./Editor.module.css";
function initialEditorState(editor: LexicalEditor): void { const root = $getRoot(); const paragraph = $createParagraphNode(); const text = $createTextNode(); paragraph.append(text); root.append(paragraph);}
export default Editor() { const room = useRoom(); const initialConfig = { // NOTE: This is critical for collaboration plugin to set editor state to null. It // would indicate that the editor should not try to set any default state // (not even empty one), and let collaboration plugin do it instead editorState: null, namespace: "Demo", nodes: [], onError: (error: unknown) => { throw error; }, theme: {}, };
return ( <div className={styles.container}> <LexicalComposer initialConfig={initialConfig}> <RichTextPlugin contentEditable={<ContentEditable className={styles.editor} />} placeholder={ <div className={styles.placeholder}>Start typing here…</div> } ErrorBoundary={LexicalErrorBoundary} /> <CollaborationPlugin id="yjs-plugin" providerFactory={(id, yjsDocMap) => { const doc = new Y.Doc(); yjsDocMap.set(id, doc); const provider = new LiveblocksProvider(room, doc) as Provider; return provider; }} initialEditorState={initialEditorState} shouldBootstrap={true} /> </LexicalComposer> </div> );}

Add collaboration to your product today

We use cookies to collect data to improve your experience on our site. Read our Privacy Policy to learn more.