yrby

lexxy-realtime · a separate gem, built on yrby

Collaborative editing for Lexxy

Lexxy is Basecamp's rich text editor for Action Text, built on Lexical. lexxy-realtime lets several people type in the same field and see each other's text and cursors as they go. You add one line to the model and one to the form, then run a generator.

lexxy-realtime installs yrby-rails and yrby-client for you and does the editor setup. If you use a different editor, or no editor, use yrby-rails directly.

app/models/post.rbmodel
class Post < ApplicationRecord  has_collaborative_rich_text :bodyend
app/views/posts/_form.html.erbview
<%= form.collaborative_rich_textarea :body %>
terminal
bin/rails generate lexxy_realtime:install && bin/rails db:migrate

Import lexxy-realtime wherever you import Lexxy, and fill in the authorized? method in the generated channel. The generated method returns false, so the channel rejects everyone until you change it. Then open the form in two browsers and type.

post.body is still Action Text.

While people are editing, lexxy-realtime keeps the document in yrby's Y::Document tables. After each change, it renders the document to HTML in Ruby with Y::Lexxy and saves the result to post.body. That HTML matches what Lexxy would have submitted itself, so search, mailers, and show pages work without changes.

Watch the saved HTML update as you type →

Each field gets its own signed token.

The form helper renders a signed GlobalID for the record and field. The channel looks up the record from it, then calls your authorized? method. A token for :body only opens :body, and the channel rejects a token that has been tampered with or has expired. So the browser can only join documents your page gave it a token for.

Custom nodes and encryption.

Any custom Lexical nodes you've registered sync like the rest of the document. When Y::Lexxy doesn't know a node, it still writes the node's text into the saved HTML.

To encrypt a field, pass encrypted: true to has_collaborative_rich_text. Both the Action Text body and the collaborative document are then stored with Active Record encryption.

Built on yrby.

lexxy-realtime is a small layer on top of yrby, which the rest of this site documents. yrby does the syncing, the saving, and the HTML rendering, over Action Cable or AnyCable. If you use import maps, the generator pins the JavaScript included in the gem. If you use a bundler, install the lexxy-realtime npm package. Either way, it reuses the copy of Lexical that Lexxy already loads.

bundle add lexxy-realtime  ·  bin/rails generate lexxy_realtime:install