Examples

Real-time Collaboration (Yjs)

Two editors bridged by Yjs — awareness gives you live cursors and the shared review ledger (comments, track changes, AI suggestions all replicate). Pass textSync: true to also bind the HTML body to a shared Y.Text so concurrent typing merges via CRDT instead of last-write-wins.

Alice

Welcome Alice. Type anything — Bob will see your cursor live.

Bob

Welcome Bob. You and Alice share the review ledger.

Example code

<link rel="stylesheet" href="/richtexteditor/rte_theme_default.css" />
        <script type="text/javascript" src="/richtexteditor/rte.js"></script>
        <script type="text/javascript" src='/richtexteditor/plugins/all_plugins.js'></script>

        <div style="display:grid; gap:14px; grid-template-columns:1fr; margin-top:10px;">
            <div><strong>Alice</strong><div id="yjs_a"><p>Welcome Alice. Type anything &mdash; Bob will see your cursor live.</p></div></div>
            <div><strong>Bob</strong><div id="yjs_b"><p>Welcome Bob. You and Alice share the review ledger.</p></div></div>
        </div>

        <script type="module">
            // Peer-dependency imports — customers use npm or a provider of their choice.
            import * as Y from "https://esm.sh/yjs@13.6.27";
            import { Awareness } from "https://esm.sh/y-protocols@1.0.6/awareness?deps=yjs@13.6.27";

            var edA = new RichTextEditor("#yjs_a", { commentsEnabled: true, trackChangesEnabled: true, currentUser: { id: "alice", name: "Alice", color: "#2563eb" } });
            var edB = new RichTextEditor("#yjs_b", { commentsEnabled: true, trackChangesEnabled: true, currentUser: { id: "bob", name: "Bob", color: "#dc2626" } });

            // Two Y.Docs bridged in-memory so this single-tab demo behaves like two browsers.
            const docA = new Y.Doc(), docB = new Y.Doc();
            const awA = new Awareness(docA), awB = new Awareness(docB);
            docA.on("update", function (u, o) { if (o !== "remote") Y.applyUpdate(docB, u, "remote"); });
            docB.on("update", function (u, o) { if (o !== "remote") Y.applyUpdate(docA, u, "remote"); });

            function waitAttach(ed, opts) {
                if (!ed.collab) { setTimeout(function () { waitAttach(ed, opts); }, 50); return; }
                ed.collab.attach(opts);
            }
            waitAttach(edA, { doc: docA, provider: { awareness: awA }, user: { id: "alice", name: "Alice", color: "#2563eb" }, textSync: true });
            waitAttach(edB, { doc: docB, provider: { awareness: awB }, user: { id: "bob", name: "Bob", color: "#dc2626" }, textSync: true });
        </script>