Agora
Client

Client hooks

The React package — the provider and its config, the hooks and which one to reach for, why the client never hard-codes an engine, and how sessions are reference counted.

@adonis-agora/collaboration-client is the React half. It is engine-agnostic on purpose: it asks the server which engine a document uses and picks the matching transport, so a component that edits researches/42/writing does not change when that document moves from the embedded Yjs server to a worker at the edge.

pnpm add @adonis-agora/collaboration-client

The provider

Everything runs under one provider, mounted once near the root:

import { CollaborationProvider } from '@adonis-agora/collaboration-client'

<CollaborationProvider baseUrl={window.location.origin}>
  <App />
</CollaborationProvider>
PropPurpose
baseUrlyour Adonis origin. Optional — falls back to location.origin, so a same-origin app can leave it out entirely
getHeaderscalled per request — return the auth headers your API needs. A function, so a rotating token is picked up without a remount
createTransportoverride the transport factory — tests, or an engine of your own
fetchImploverride fetch — tests and SSR

The provider's real job is holding the session map: one DocSession per document name, each owning a Y.Doc, a transport and a reconnect loop. Sessions are created on demand and reference counted — the socket opens with the first hook that mounts and closes when the last one unmounts, while the Y.Doc stays in the map, so navigating back resumes on the document you left instead of starting from an empty one. See Sessions.

Mount it above the router, not inside a page

A provider that remounts on navigation throws its whole session map away — documents included — so every route change starts from scratch. Put it in the layout.

The hooks

HookReturnsBacked by
useCollabDocthe shared Y.Doc (and its collabDoc view) plus status, synced and errorWebSocket
useAutomergeDocthe Automerge document plus change(fn), synced and pendingChangesWebSocket
useCollabEditoran editor-agnostic { state, update } view, plus synced and peersWebSocket
useAwarenesspeers — everyone else in the room — plus setLocalState to publish yourselfWebSocket
useExcalidrawSyncnothing — it wires a Y.Doc (or a collabDoc) to Excalidraw's imperative APIWebSocket
useCommentscomments, create, resolve, remove, refreshREST
useVersionsversions, create, restore, refreshREST

Two things follow from that last column. The REST-backed hooks keep working while the socket is down — they open no session at all, so a page with no editor on it can list a document's comments — and they are not live: new comments appear on refresh(), not the instant someone else posts one.

Picking a document hook

Is the server's engine for this document 'automerge'?
├── yes → useAutomergeDoc
└── no  → is there an editor adapter for your surface?
          ├── yes (Excalidraw, tldraw, plain text) → useCollabEditor
          └── no  (Tiptap, CodeMirror, custom)     → useCollabDoc, bind the Y.Doc yourself

useCollabDoc gives you the raw Y.Doc and gets out of the way — the right choice for Tiptap, where the editor's own extension does the binding. useCollabEditor is a level up: an adapter maps a whole scene in and out of one document key, so the component only ever sees { state, update }. See Editors.

useCollabDoc fails on an Automerge document

An Automerge document cannot back a Y.Doc, so there is no honest way to return one. Pointing useCollabDoc at a document the server resolves to automerge surfaces a clear message on the hook's error — it does not throw out of the render, so check error, do not wrap the hook — rather than handing back an empty document that never syncs. See Automerge.

Below the hooks

Every hook is built on exported pieces you can use directly when a hook does not fit — a non-React frontend, a script, a test:

  • DocSession — the token fetch, transport and reconnect loop for one document, plus the retain/release/stop/destroy lifecycle the hooks drive for you.
  • fetchToken, listComments, createComment, resolveComment, deleteComment, listVersions, createVersion, restoreVersion — the REST client, plus CollabRestError.
  • HocuspocusCollabTransport, PartyKitCollabTransport, PartyServerCollabTransport and defaultTransportFactory — the transports and the factory that chooses between them.

On this page