Skip to main content

Y-prosemirror

What is y-prosemirror?

y-prosemirror is a plugin that integrates Yjs (a CRDT framework for real-time collaboration) with ProseMirror (a toolkit for building rich text editors). It enables real-time collaboration features in ProseMirror editors.

Features

  • Real-time synchronization
  • Shared cursors and selections
  • Undo/Redo functionality
  • Offline editing support
  • Conflict resolution

Main Components

  • ySyncPlugin: Synchronizes ProseMirror with Yjs
  • yCursorPlugin: Adds shared cursors and selections
  • yUndoPlugin: Provides Yjs-aware undo/redo functionality

Basic example how to setup y-prosemirror

import * as Y from "yjs";
import { HocuspocusProvider } from "@hocuspocus/provider";
import {
ySyncPlugin,
yCursorPlugin,
yUndoPlugin,
undo,
redo,
} from "y-prosemirror";
import { EditorState } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
import { Schema } from "prosemirror-model";

// Create a Yjs document
const ydoc = new Y.Doc();

// Set up a websocket provider
const provider = new HocuspocusProvider({
url: 'wss://notebook.lnchbx.com',
name: 'notebook id',
document: ydoc,
parameters: { },
token: 'Lunchbox token'
})

// Get the shared type
const yXmlFragment = ydoc.getXmlFragment("prosemirror");

// Define your schema
const schema = new Schema({
nodes: {
doc: { content: "paragraph+" },
paragraph: { content: "text*", toDOM: () => ["p", 0] },
text: { inline: true },
},
});

// Create ProseMirror state with y-prosemirror plugins
const state = EditorState.create({
schema,
plugins: [
ySyncPlugin(yXmlFragment),
yCursorPlugin(provider.awareness),
yUndoPlugin(),
],
});

// Create and mount the editor
const view = new EditorView(document.querySelector("#editor"), { state });

// Set up undo/redo commands
document
.querySelector("#undo")
.addEventListener("click", () => undo(view.state, view.dispatch));
document
.querySelector("#redo")
.addEventListener("click", () => redo(view.state, view.dispatch));