Modifying Yjs document data with the REST API

Liveblocks allows you to update your Yjs document data, or yDoc, from the REST API, helpful for sending updates from the server. This is made possible through the Send a binary Yjs update API.

Updating a Yjs document

Updating a Yjs document requires you to create a binary update, before sending it to the REST API. Here’s an example in a serverless endpoint.

import * as Y from "yjs";
const SECRET_KEY = "sk_prod_xxxxxxxxxxxxxxxxxxxxxxxx";const roomId = "my-room-name";
export async function POST() { // Create a Yjs document const yDoc = new Y.Doc();
// Create your data structures and make your update const yText = yDoc.getText("text"); yText.insert(0, "Hello world");
// Encode the document state as an update message const yUpdate = Y.encodeStateAsUpdate(yDoc);
// Insert the update await fetch(`https://api.liveblocks.io/v2/rooms/${roomId}/ydoc`, { method: "PUT", headers: { "Authorization:": `Bearer ${SECRET_KEY}`, }, body: yUpdate, });}

Initializing a Yjs document

It’s also possible to create a new room with an initial Yjs document. To do this, call the Create room API, then send the update as before.

import * as Y from "yjs";
const SECRET_KEY = "sk_prod_xxxxxxxxxxxxxxxxxxxxxxxx";const roomId = "my-room-name";
export async function POST() { // Create a Yjs document const yDoc = new Y.Doc();
// Create your data structures and make your update const yText = yDoc.getText("text"); yText.insert(0, "Hello world");
// Encode the document state as an update message const yUpdate = Y.encodeStateAsUpdate(yDoc);
// Create the new room await fetch(`https://api.liveblocks.io/v2/rooms/`, { method: "POST", headers: { "Authorization:": `Bearer ${SECRET_KEY}`, }, body: JSON.stringify({ id: roomId, defaultAccesses: ["room:write"], }), });
// Initialize the Yjs document with the update await fetch(`https://api.liveblocks.io/v2/rooms/${roomId}/ydoc`, { method: "PUT", headers: { "Authorization:": `Bearer ${SECRET_KEY}`, }, body: yUpdate, });}

Each editor works differently

Note that each text and code editor may work differently, and may include specific functions for creating binary updates. For example, this is how to initialize a Slate document:

import * as Y from "yjs";import { slateNodesToInsertDelta } from "@slate-yjs/core";
const SECRET_KEY = "sk_prod_xxxxxxxxxxxxxxxxxxxxxxxx";const roomId = "my-room-name";
export async function POST() { // Create a Yjs document const yDoc = new Y.Doc();
// The Slate document we're creating const slateDoc = { type: "paragraph", children: [{ text: "Hello world" }], };
// Create your data structures and make your update const insertDelta = slateNodesToInsertDelta(slateDoc); (yDoc.get("content", Y.XmlText) as Y.XmlText).applyDelta(insertDelta);
// Encode the document state as an update message const yUpdate = Y.encodeStateAsUpdate(yDoc);
// Create the new room await fetch(`https://api.liveblocks.io/v2/rooms/`, { method: "POST", headers: { "Authorization:": `Bearer ${SECRET_KEY}`, }, body: JSON.stringify({ id: roomId, defaultAccesses: ["room:write"], }), });
// Initialize the Yjs document with the update await fetch(`https://api.liveblocks.io/v2/rooms/${roomId}/ydoc`, { method: "PUT", headers: { "Authorization:": `Bearer ${SECRET_KEY}`, }, body: yUpdate, });}