@liveblocks/node
provides you with Node.js APIs for
authenticating Liveblocks users and for
implementing webhook handlers. This library is only intended
for use in your Node.js back end.
The Liveblocks
client is new in 1.2, and offers access to our REST API.
To authorize your users with Liveblocks, you have the choice between two different APIs.
Liveblocks.prepareSession
is recommended for most
applications.Liveblocks.identifyUser
is best if you’re using fine-grained
permissions with our REST API.The purpose of this API is to help you implement your custom authentication back
end (i.e. the server part of the diagram). You use the
liveblocks.prepareSession()
API if you’d like to issue
access tokens from your back end.
To implement your back end, follow these steps:
The userId
(required) is an identifier to uniquely identifies
your user with Liveblocks. This value will be used when counting
unique MAUs in your Liveblocks dashboard.
The userInfo
(optional) is any custom JSON value, which can be
attached to static metadata to this user’s session. This will be
publicly visible to all other people in the room. Useful for
metadata like the user’s full name, or their avatar URL.
Finally, authorize the session. This step makes the HTTP call to the Liveblocks servers. Liveblocks will return a signed access token that you can return to your client.
Here’s a real-world example of access tokens in a Next.js route handler/endpoint. You can find examples for other frameworks in our authentication section.
The purpose of this API is to help you implement your custom authentication back
end (i.e. the server part of the diagram). You use the
liveblocks.identifyUser()
API if you’d like to issue
ID tokens from your back end. An ID token does
not grant any permissions in the token directly. Instead, it only securely
identifies your user, and then uses any permissions set via the Permissions
REST API to decide whether to allow the user on a room-by-room basis.
Use this approach if you’d like Liveblocks to be the source of truth for your user’s permissions.
Implement your back end endpoint as follows:
userId
(required) is a string identifier to uniquely identify your user with
Liveblocks. This value will be used when counting unique MAUs in your Liveblocks
dashboard. You can refer to these user IDs in the Permissions REST API when
assigning group permissions.
groupIds
(optional) can be used to specify which groups this user belongs to.
These are arbitrary identifiers that make sense to your app, and that you can
refer to in the Permissions REST API when assigning group permissions.
userInfo
(optional) is any custom JSON value, which you can use to attach
static metadata to this user’s session. This will be publicly visible to all
other people in the room. Useful for metadata like the user’s full name, or
their avatar URL.
Here’s a real-world example of ID tokens in a Next.js route handler/endpoint. You can find examples for other frameworks in our authentication section.
Returns a list of rooms that are in the current project. The project is
determined by the secret key you’re using. Rooms are sorted by creation time,
with the newest room at index 0
. This is a wrapper around the
Get Rooms API and returns
the same response.
A number of options are also available, enabling you to filter for certain rooms.
The query
option also allows you to pass a
query language string
instead of a query
object.
You can use nextCursor
to paginate rooms. In this example, when getNextPage
is called, the next set of rooms is added to pages
.
Programmatically creates a new room from a room ID. The defaultAccesses
option
is required. Setting defaultAccesses
to ["room:write"]
creates a public
room, whereas setting it to []
will create a private room that needs
ID token permission to enter. This is a wrapper
around the Create Room API
and returns the same response.
A number of room creation options are available, allowing you to set permissions and attach custom metadata.
Group and user permissions are only used with ID token authorization, learn more about managing permission with ID tokens.
Returns a room. Throws an error if the room isn’t found. This is a wrapper around the Get Room API and returns the same response.
Updates properties on a room. Throws an error if the room isn’t found. This is a wrapper around the Update Room API and returns the same response.
Permissions and metadata properties can be updated on the room. Note that you
need only pass the properties you’re updating. Setting a property to null
will
delete the property.
Group and user permissions are only used with ID token authorization, learn more about managing permission with ID tokens.
Deletes a room. Throws an error if the room isn’t found. This is a wrapper around the Delete Room API and returns no response.
Permanently updates a room’s ID. newRoomId
will replace roomId
. Note that
this will disconnect connected users from the room, but this can be worked
around. Throws an error if the room isn’t found. This is a wrapper around the
Update Room API
and returns the same response.
When a room’s ID is changed it disconnects all users that are currently
connected. To redirect connected users to the new room you can use
useErrorListener
or
room.subscribe("error")
in your application to get the new room’s ID, and redirect users to the renamed
room.
Returns a list of users that are currently present in the room. Throws an error if the room isn’t found. This is a wrapper around the Get Active Users API and returns the same response.
Broadcasts a custom event to the room. Throws an error if the room isn’t found. This is a wrapper around the Broadcast Event API and returns no response.
You can respond to custom events on the front end with
useBroadcastEvent
and
room.subscribe("event")
.
When receiving an event sent with Liveblocks.broadcastEvent
, user
will be
null
and connectionId
will be -1
.
Returns the contents of a room’s Storage tree. By default, returns Storage in LSON format. Throws an error if the room isn’t found. This is a wrapper around the Get Storage Document API and returns the same response.
LSON is a custom Liveblocks format that preserves information about the
conflict-free data types used. By default, getStorageDocument
returns Storage
in this format. This is the same as using "plain-json"
in the second argument.
You can also retrieve Storage as JSON by passing "json"
into the second
argument.
Initializes a room’s Storage tree with given LSON data. To use this, the room must have already been created and have empty Storage. Throws an error if the room isn’t found. Calling this will disconnect all active users from the room. This is a wrapper around the Initialize Storage Document API and returns the same response.
LSON is a custom Liveblocks format that preserves information about
conflict-free data types. The easiest way to create it is using the
toPlainLson
helper provided by @liveblocks/client
. Note that your Storage
root should always be a LiveObject
.
It’s also possible to create plain LSON manually, without the helper function.
Deletes a room’s Storage data. Calling this will disconnect all active users from the room. Throws an error if the room isn’t found. This is a wrapper around the Delete Storage Document API and returns no response.
Returns a JSON representation of a room’s Yjs document. Throws an error if the room isn’t found. This is a wrapper around the Get Yjs Document API and returns the same response.
A number of options are available.
Send a Yjs binary update to a room’s Yjs document. You can use this to update or initialize the room’s Yjs document. Throws an error if the room isn’t found. This is a wrapper around the Send a Binary Yjs Update API and returns no response.
Here’s an example of how to update a room’s Yjs document with your changes.
To update a subdocument instead of the main document, pass its guid
.
To create a new room and initialize its Yjs document, call
liveblocks.createRoom
before sending the binary update.
Note that each text and code editor handles binary updates in a different way,
and may use a different Yjs shared type, for example
Y.XmlFragment
instead
of Y.Text
.
Create a binary update with Slate:
Create a binary update with Tiptap:
Read the Yjs documentation to learn more about creating binary updates.
Return a room’s Yjs document as a single binary update. You can use this to get a copy of your Yjs document in your back end. Throws an error if the room isn’t found. This is a wrapper around the Get Yjs Document Encoded as a Binary Yjs Update API and returns the same response.
To return a subdocument instead of the main document, pass its guid
.
Read the Yjs documentation to learn more about using binary updates.
Creates a schema that can be used to enforce a room’s Storage data structure. The schema consists of a unique name, and a body which specifies the data shape of the room in Liveblocks schema syntax. This is a wrapper around the Create Schema API and returns the same response.
Read the schema validation page to learn more.
Returns a schema from its ID. A schema’s ID is a combination of its name and
version, for example the ID for version 1
of my-schema-name
is
my-schema-name@1
. This is a wrapper around the
Get Schema API
and returns the same response.
Read the schema validation page to learn more.
Updates a schema’s body and increments its version. A schema’s body specifies
the data shape of the room in Liveblocks
schema syntax. Find the schema by its
ID, a combination of its name and version, for example the ID for version 1
of
my-schema-name
is my-schema-name@1
. This is a wrapper around the
Update Schema API
and returns the same response.
Read the schema validation page to learn more.
Deletes a schema. This is only allowed if the schema is not attached to a room.
Find the schema by its ID, a combination of its name and version, for example
the ID for version 1
of my-schema-name
is my-schema-name@1
. This is a
wrapper around the
Delete Schema API and
returns no response.
Read the schema validation page to learn more.
Returns the schema attached to a room. Throws an error if the room isn’t found. This is a wrapper around the Get Schema By Room API and returns the same response.
Read the schema validation page to learn more.
Attaches a schema to a room, and instantly enables runtime schema validation in
it. Attach the schema by its ID, a combination of its name and version, for
example the ID for version 1
of my-schema-name
is my-schema-name@1
. This
is a wrapper around the
Attach Schema to a Room API
and returns the same response.
If the current contents of the room’s Storage do not match the schema, attaching will fail and the error message will give details on why the schema failed to attach. It’ll also throw an error if the room isn’t found.
Read the schema validation page to learn more.
Detaches a schema from a room. This is a wrapper around the Detach Schema from a Room API and returns no response.
Returns a list of threads found inside a room. Throws an error if the room isn’t found. This is a wrapper around the Get Room Threads API and returns the same response.
It’s also possible to filter threads by their string, boolean, and number
metadata using a query parameter. You can also pass startsWith
to match the
start of a string.
You can also pass a
query language string
instead of a query
object.
Creates a new thread within a specific room, using room ID and thread data. This is a wrapper around the Create Thread API and returns the new thread.
A comment’s body is an array of paragraphs, each containing child nodes. Here’s
an example of how to construct a comment’s body, which can be submitted under
data.comment.body
.
This method has a number of options, allowing for custom metadata and a creation date for the comment.
Returns a thread. Throws an error if the room or thread isn’t found. This is a wrapper around the Get Thread API and returns the same response.
Returns a list of participants found inside a thread. A participant is a user who has commented or been mentioned in the thread. Throws an error if the room or thread isn’t found. This is a wrapper around the Get Thread Participants API and returns the same response.
Updates the metadata of a specific thread within a room. This method allows you to modify the metadata of a thread, including user information and the date of the last update. Throws an error if the room or thread isn’t found. This is a wrapper around the Update Thread Metadata API and returns the updated metadata.
Metadata can be a string
, number
, or boolean
. You can also use null
to
remove metadata from a thread. Here’s an example using every option.
Marks a thread as resolved, which means it sets the resolved
property on the
specified thread to true
. Takes a userId
, which is the ID of the user that
resolved the thread. Throws an error if the room or thread isn’t found. This is
a wrapper around the
Mark Thread As Resolved API
and returns the same response.
Marks a thread as unresolved, which means it sets the resolved
property on the
specified thread to false
. Takes a userId
, which is the ID of the user that
unresolved the thread. Throws an error if the room or thread isn’t found. This
is a wrapper around the
Mark Thread As Unresolved API
and returns the same response.
Deletes a thread. Throws an error if the room or thread isn’t found. This is a wrapper around the Delete Thread API and returns no response.
Creates a new comment in a specific thread within a room. This method allows users to add comments to a conversation thread, specifying the user who made the comment and the content of the comment. This method is a wrapper around the Get Comment API and returns the new comment.
A comment’s body is an array of paragraphs, each containing child nodes. Here’s
an example of how to construct a comment’s body, which can be submitted under
data.body
.
This method has a number of options, including the option to add a custom creation date to the comment.
Returns a comment. Throws an error if the room, thread, or comment isn’t found. This is a wrapper around the Get Comment API and returns the same response.
Edits an existing comment in a specific thread within a room. This method allows users to update the content of their previously posted comments, with the option to specify the time of the edit. Throws an error if the comment isn’t found. This is a wrapper around the Edit Comment API and returns the updated comment.
A comment’s body is an array of paragraphs, each containing child nodes. Here’s
an example of how to construct a comment’s body, which can be submitted under
data.body
.
Deletes a specific comment from a thread within a room. If there are no remaining comments in the thread, the thread is also deleted. This method throws an error if the comment isn’t found. This is a wrapper around the Delete Comment API and returns no response.
Adds a reaction to a specific comment in a thread within a room. Throws an error if the comment isn’t found or if the user has already added the same reaction on the comment. This is a wrapper around the Add Comment Reaction API and returns the new reaction.
Removes a reaction from a specific comment in a thread within a room. Throws an error if the comment reaction isn’t found. This is a wrapper around the Remove Comment Reaction API and returns no response.
Returns a user’s notification settings for a specific room. This is a wrapper around the Get Room Notification Settings API.
Updates a user’s notification settings for a specific room. This is a wrapper around the Update Room Notification Settings API.
Deletes a user’s notification settings for a specific room. This is a wrapper around the Delete Room Notification Settings API.
Returns a list of a user’s inbox notifications. This is a wrapper around the Get Inbox Notifications API. It also provides an unread query parameter to filter unread notifications.
Returns a user’s inbox notification. This is a wrapper around the Get Inbox Notification API.
Triggers a custom inbox notification. kind
must start with a $
, and
represents the type of notification. activityData
is used to send custom data
with the notification, and properties can have string
, number
, or boolean
values. This is a wrapper around the
Trigger Inbox Notification API.
To type custom notifications, edit the ActivitiesData
type in your config
file.
Deletes a user’s inbox notification. This is a wrapper around the Delete Inbox Notification API.
Deletes all the user’s inbox notifications. This is a wrapper around the Delete Inbox Notifications API.
Errors in our API methods, such as network failures, invalid arguments, or
server-side issues, are reported through the LiveblocksError
class. This
custom error class extends the standard JavaScript
Error
and includes a status
property, which provides the HTTP status code for the
error, such as 404 for not found or 500 for server errors.
Example of handling errors in a typical API call:
Returns an array of each user’s ID that has been mentioned in a CommentBody
(found under comment.body
).
This is most commonly used in combination with the
Comments API functions, for
example getComment
.
Here’s an example with a custom CommentBody
.
Used to convert a CommentBody
(found under comment.body
) into either a plain
string, Markdown, HTML, or a custom format.
This is most commonly used in combination with the
Comments API functions, for
example getComment
.
A number of options are also available.
Here are a number of different formatting examples derived from the same
CommentBody
.
The WebhookHandler
class is a helper to handle webhook requests from
Liveblocks.
It’s initialized with a signing secret that you can find in your project’s webhook page.
Verifies the request and returns the event. Note that rawBody
takes the body
as a string
.
Some frameworks parse request bodies into objects, which means using
JSON.stringify
may be necessary.
Type guard to check if a received webhook event is a
ThreadNotificationEvent
send
from Comments. Particularly helpful when creating
thread notification emails
with webhooks.
The check is made against the event type and event data kind.
Type guard to check if a received webhook event is a
TextMentionNotificationEvent
sent from Text Editor. Particularly helpful for identifying text mentions when
sending email notifications.
The check is made against the event type and event data kind.
The purpose of authorize()
was to help you implement your custom
authentication back end. It generates old-style single-room tokens.
Please refer to our upgrade guide if you’re
using the authorize
function in your back end, and adopt
Liveblocks.prepareSession
or
Liveblocks.identifyUser
APIs instead.
We use cookies to collect data to improve your experience on our site. Read our Privacy Policy to learn more.