A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://liveblocks.io/docs/api-reference/liveblocks-react below:

@liveblocks/react | API Reference

@liveblocks/react provides you with React bindings for our realtime collaboration APIs, built on top of WebSockets. Read our getting started guides to learn more.

Suspense

All Liveblocks React components and hooks can be exported from two different locations, @liveblocks/react/suspense and @liveblocks/react. This is because Liveblocks provides two types of hooks; those that support React Suspense, and those that don’t.

We recommend importing from @liveblocks/react/suspense and using Suspense by default, as it often makes it easier to build your collaborative application.

Suspense hooks

Suspense hooks can be wrapped in ClientSideSuspense, which acts as a loading spinner for any components below it. When using this, all components below will only render once their hook contents have been loaded.

Advanced hooks using the { ..., error, isLoading } syntax, such as useThreads, can also use ErrorBoundary to render an error if the hook runs into a problem.

An advantage of Suspense hooks is that you can have multiple different hooks in your tree, and you only need a single ClientSideSuspense component to render a loading spinner for all of them.

Regular hooks

Regular hooks often return null whilst a component is loading, and you must check for this to render a loading spinner.

Advanced hooks using the { ..., error, isLoading } syntax, such as useThreads, require you to make sure there isn’t a problem before using the data.

ClientSideSuspense

Liveblocks provides a component named ClientSideSuspense which works as a replacement for Suspense. This is helpful as our Suspense hooks will throw an error when they’re run on the server, and this component avoids this issue by always rendering the fallback on the server.

Loading spinners

Instead of wrapping your entire Liveblocks application inside a single ClientSideSuspense component, you can use multiple of these components in different parts of your application, and each will work as a loading fallback for any components further down your tree.

This is a great way to build a static skeleton around your dynamic collaborative application.

Liveblocks LiveblocksProvider

Sets up a client for connecting to Liveblocks, and is the recommended way to do this for React apps. You must define either authEndpoint or publicApiKey. Resolver functions should be placed inside here, and a number of other options are available, which correspond with those passed to createClient. Unlike RoomProvider, LiveblocksProvider doesn’t call Liveblocks servers when mounted, and it should be placed higher in your app’s component tree.

Props LiveblocksProvider with public key

When creating a client with a public key, you don’t need to set up an authorization endpoint. We only recommend using a public key when prototyping, or on public landing pages, as it makes it possible for end users to access any room’s data. You should instead use an auth endpoint.

LiveblocksProvider with auth endpoint

If you are not using a public key, you need to set up your own authEndpoint. Please refer to our Authentication guide.

LiveblocksProvider with auth endpoint callback

If you need to add additional headers or use your own function to call your endpoint, authEndpoint can be provided as a custom callback. You should return the token created with Liveblocks.prepareSession or liveblocks.identifyUser, learn more in authentication guide.

room is the room ID that the user is connecting to. When using Notifications, room can be undefined, as the client is requesting a token that grants access to multiple rooms, rather than a specific room.

Fetch your endpoint

Here’s an example of fetching your API endpoint at /api/liveblocks-auth within the callback.

Token details

You should return the token created with Liveblocks.prepareSession or liveblocks.identifyUser. These are the values the functions can return.

  1. A valid token, it returns a { "token": "..." } shaped response.
  2. A token that explicitly forbids access, it returns an { "error": "forbidden", "reason": "..." } shaped response. If this is returned, the client will disconnect and won't keep trying to authorize.

Any other error will be treated as an unexpected error, after which the client will retry the request until it receives either 1. or 2.

WebSocket throttle

By default, the client throttles the WebSocket messages sent to one every 100 milliseconds, which translates to 10 updates per second. It’s possible to override that configuration with the throttle option with a value between 16 and 1000 milliseconds.

This option is helpful for smoothing out realtime animations in your application, as you can effectively increase the framerate without using any interpolation. Here are some examples with their approximate frames per second (FPS) values.

Prevent users losing unsaved changes

Liveblocks usually synchronizes milliseconds after a local change, but if a user immediately closes their tab, or if they have a slow connection, it may take longer for changes to synchronize. Enabling preventUnsavedChanges will stop tabs with unsaved changes closing, by opening a dialog that warns users. In usual circumstances, it will very rarely trigger.

More specifically, this option triggers when:

Internally, this option uses the beforeunload event.

Lost connection timeout

If you’re connected to a room and briefly lose connection, Liveblocks will reconnect automatically and quickly. However, if reconnecting takes longer than usual, for example if your network is offline, then the room will emit an event informing you about this.

How quickly this event is triggered can be configured with the lostConnectionTimeout setting, and it takes a number in milliseconds. lostConnectionTimeout can be set between 1000 and 30000 milliseconds. The default is 5000, or 5 seconds.

You can listen to the event with useLostConnectionListener. Note that this also affects when others are reset to an empty array after a disconnection. This helps prevent temporary flashes in your application as a user quickly disconnects and reconnects. For a demonstration of this behavior, see our connection status example.

Background keep-alive timeout

By default, Liveblocks applications will maintain an active WebSocket connection to the Liveblocks servers, even when running in a browser tab that’s in the background. However, if you’d prefer for background tabs to disconnect after a period of inactivity, then you can use backgroundKeepAliveTimeout.

When backgroundKeepAliveTimeout is specified, the client will automatically disconnect applications that have been in an unfocused background tab for at least the specified time. When the browser tab is refocused, the client will immediately reconnect to the room and synchronize the document.

backgroundKeepAliveTimeout accepts a number in milliseconds—we advise using a value of at least a few minutes, to avoid unnecessary disconnections.

resolveUsers

Comments stores user IDs in its system, but no other user information. To display user information in Comments components, such as a user’s name or avatar, you need to resolve these IDs into user objects. This function receives a list of user IDs and you should return a list of user objects of the same size, in the same order.

User IDs are automatically resolved in batches with a maximum of 50 users per batch to optimize performance and prevent overwhelming your user resolution function.

The name and avatar you return are rendered in Thread components.

User objects

The user objects returned by the resolver function take the shape of UserMeta["info"], which contains name and avatar by default. These two values are optional, though if you’re using the Comments default components, they are necessary. Here’s an example of userIds and the exact values returned.

You can also return custom information, for example, a user’s color:

Accessing user data

You can access any values set within resolveUsers with the useUser hook.

resolveRoomsInfo

When using Notifications with Comments, room IDs will be used to contextualize notifications (e.g. “Chris mentioned you in room-id”) in the InboxNotification component. To replace room IDs with more fitting names (e.g. document names, “Chris mentioned you in Document A”), you can provide a resolver function to the resolveRoomsInfo option in LiveblocksProvider.

This resolver function will receive a list of room IDs and should return a list of room info objects of the same size and in the same order.

In addition to the room’s name, you can also provide a room’s URL as the url property. If you do so, the InboxNotification component will automatically use it. It’s possible to use an inbox notification’s roomId property to construct a room’s URL directly in React and set it on InboxNotification via href, but the room ID might not be enough for you to construct the URL , you might need to call your backend for example. In that case, providing it via resolveRoomsInfo is the preferred way.

resolveMentionSuggestions

To enable creating mentions in Comments, you can provide a resolver function to the resolveMentionSuggestions option in LiveblocksProvider. These mentions will be displayed in the Composer component.

This resolver function will receive the mention currently being typed (e.g. when writing “@jane”, text will be jane) and should return a list of user IDs matching that text. This function will be called every time the text changes but with some debouncing.

LiveblocksProvider for Node.js

To use @liveblocks/client in Node.js, you need to provide WebSocket and fetch polyfills. As polyfills, we recommend installing ws and node-fetch.

Then, pass them to the LiveblocksProvider polyfill option as below.

Note that node-fetch v3+ does not support CommonJS. If you are using CommonJS, downgrade node-fetch to v2.

LiveblocksProvider for React Native

To use @liveblocks/client with React Native, you need to add an atob polyfill. As a polyfill, we recommend installing base-64.

Then you can pass the decode function to our atob polyfill option when you create the client.

createLiveblocksContext

Creates a LiveblocksProvider and a set of typed hooks. Note that any LiveblocksProvider created in this way takes no props, because it uses settings from the client instead. We recommend using it in liveblocks.config.ts and re-exporting your typed hooks like below.

While createRoomContext offers APIs for interacting with rooms (e.g. Presence, Storage, and Comments), createLiveblocksContext offers APIs for interacting with Liveblocks features that are not tied to a specific room (e.g. Notifications).

useClient

Returns the client of the nearest LiveblocksProvider above in the React component tree.

useErrorListener

Listen to potential Liveblocks errors. Examples of errors include room connection errors, errors creating threads, and errors deleting notifications. Each error has a message string, and a context object which has different values for each error type. context always contains an error type and roomId.

There are many different errors, and each can be handled separately by checking the value of error.context.type. Below we’ve listed each error and the context it provides.

Hook changes in 2.16

The behavior of this hook changed in 2.16. Previously, this hook had to be in a RoomProvider context, and would only trigger for connection errors in the current room. Since 2.16, this hook only requires a LiveblocksProvider context, and will notify about any errors, and for any room. For example, notifications are not part of rooms, and errors for these will show. See the upgrade guide for 2.16 for more details.

AI Copilots useAiChats

Returns a paginated list of AI chats created by the current user. Initially fetches the latest 50 chats.

List the user’s chats and switch between them

You can use the AiChat component alongside the hook to create an AI chat switcher. Below, each button displays the chat’s automatically generated title, and chats can be deleted with useDeleteAiChat.

Querying chats

It’s possible to return chats that match a certain query with the query option. You can filter by metadata values, or by the absence of a metadata key. Returned chats must match the entire query.

Pagination

By default, the useAiChats hook returns up to 50 chats. To fetch more, the hook provides additional fields for pagination, similar to useThreads.

Pagination example

The following example demonstrates how to use the fetchMore function to implement a “Load More” button, which fetches additional AI chats when clicked. The button is disabled while fetching is in progress.

Error handling

Error handling is another important aspect to consider when using the useAiChats hook. The error and fetchMoreError fields provide information about any errors that occurred during the initial fetch or subsequent fetch operations, respectively. You can use these fields to display appropriate error messages to the user and implement retry mechanisms if needed.

The following example shows how to display error messages for both initial loading errors and errors that occur when fetching more inbox notifications.

👉 A Suspense version of this hook is also available, which will never return a loading state and will throw error to the nearest ErrorBoundary if initial load failed.

useAiChat

Returns information about an AI chat, for example its title and metadata. Titles are automatically generated from the content of the first user message in a chat, and the AI’s response.

👉 A Suspense version of this hook is also available, which will never return a loading state and will throw error to the nearest ErrorBoundary if initial load failed.

Displaying a default title

If chat.title is undefined after an isLoading check, that means the title has not been set yet. You can display a default title in this case, and the title will be displayed once generated.

useCreateAiChat

Returns a function that creates an AI chat.

You can optionally set a title, which prevents the AI auto-generating a title from the first messages. Additionally, you can choose to set custom metadata for the chat, strings or arrays of strings.

useDeleteAiChat

Returns a function that deletes an AI chat by its ID. Use in conjunction with useAiChats to loop through each chat and add a delete button.

useSendAiMessage

Returns a function that sends a message to an AI chat, indentified by its ID. Useful for creating suggestions in empty inside chats and sending messages on behalf of the user.

You can set options related to the message being sent, such as the copilot ID to use. Alternatively, you can also override or complete the hook’s options when calling the function by passing an object to it.

You can also pass the chat ID in the function rather than the hook. This is particularly helpful in dynamic scenarios where the chat ID might not be known when calling the hook.

If needed (e.g. using the message’s ID), you can also access the newly created message.

useAiChatMessages

Returns a list of every message in an AI chat, identified by its ID. Updates in realtime using WebSockets.

RegisterAiKnowledge

Adds knowledge to all AI features on the page. AI will understand the information you pass, and will answer questions or call tools based on it. This is particularly helpful for passing user info, app state, and other small contextual knowledge.

Each knowledge source has a description string, and a value which can be either a string, object, array or JSON-serializable value that provides meaningful context for your use case. The AI uses this data, along with the accompanying description, to better understand and respond to user queries or perform actions based on the supplied context. These components can be placed anywhere in your app, so long as they’re under LiveblocksProvider.

Pass in assorted context

Passing the AI context about the current datetime, the user’s language, the page the user’s visiting, and navigable pages on your website, is an effective method for improving your chat’s replies.

When building your app, it’s worth considering which app-specific context will be helpful, for example the user’s payment plan, or a list of their projects.

Pass in user data from your auth provider

You can pass in knowledge from your auth provider, for example with useUser from Clerk. You can tell AI that the state is loading in a simple string, and it will understand.

Pass in assorted data from fetching hooks

You can pass in knowledge from data fetching hooks such as with useSWR from SWR. You can tell AI that the state is loading in a simple string, and it will understand.

Pass in text editor document data

You can pass in knowledge from your text editor, for example when using Liveblocks Tiptap.

As well as editor.getHTML(), editor.getJSON() and editor.getText() are also available when using Tiptap. Its worth trying them all, in case your AI model understands one of them better than the others.

Pass in comment data

You can also pass in knowledge from your custom Liveblocks Comments app with useThreads. This way, your AI chat will understand the context in the current room.

Pass in storage data

You can also pass in knowledge from your custom Liveblocks storage app with useStorage. This way, your AI chat will understand the context in the current room.

Props RegisterAiTool

Registers a tool that can be used by AI chats on the page. Tools allow AI to autonomously run actions, render custom components, and show confirmation or human-in-the-loop UIs within the chat.

defineAiTool is used to create a tool definition, and you can supply parameters as a JSON Schema that the AI can fill in. If you supply an execute function the AI will call it. render is used to show UI inside the chat. Below is an example of a tool that lets AI get the current weather in a given location, then renders a compoennt in the chat.

Tool that sends a toast notification

The following snippet shows a tool that lets AI send a toast notification with Sonner, then adds a message in the chat with AiTool, letting the user know that a toast was sent.

Scoping a tool to a specific chat

Tools can be scoped to specific chats by providing a chatId prop. When scoped, the tool will only be available to that specific chat.

Props Room RoomProvider

Makes a Room available in the component hierarchy below. Joins the room when the component is mounted, and automatically leaves the room when the component is unmounted. When using Sync Datastore, initial Presence values for each user, and Storage values for the room can be set.

Props Setting initial Presence

Presence is used for storing temporary user-based values, such as a user’s cursor coordinates, or their current selection. Each user has their own presence, and this is readable for all other connected users. Set your initial Presence value by using initialPresence.

Each user’s Presence resets every time they disconnect, as this is only meant for temporary data. Any JSON-serializable object is allowed (the JsonObject type).

Setting initial Storage

Storage is used to store permanent data that’s used in your application, such as shapes on a whiteboard, nodes on a flowchart, or text in a form. The first time a room is entered, you can set an initial value by using initialStorage. initialStorage is only read and set a single time, unless a new top-level property is added.

If a new top-level property is added to initialStorage, the next time a user connects, the new property will be created. Other properties will be unaffected. Any conflict-free live structures and JSON-serializable objects are allowed (the LsonObject type).

createRoomContext

Creates a RoomProvider and a set of typed hooks to use in your app. Note that any RoomProvider created in this way does not need to be nested in LiveblocksProvider, as it already has access to the client. We generally recommend typing your app using the newer method instead. When using createRoomContext it can be helpful to use it in liveblocks.config.ts and re-export your typed hooks as below.

Suspense with createRoomContext

To use the React suspense version of our hooks with createRoomContext, you can export from the suspense property instead.

Typing createRoomContext

To type your hooks, you can pass multiple different types to createRoomContext. A full explanation is in the code snippet below.

useRoom

Returns the Room of the nearest RoomProvider above in the React component tree.

Will throw when used outside of a RoomProvider. If you don’t want this hook to throw when used outside of a Room context (for example to write components in a way that they can be used both inside and outside of a Liveblocks room), you can use the { allowOutsideRoom } option:

useIsInsideRoom

Returns a boolean, true if the hook was called inside a RoomProvider context, and false otherwise.

Displaying different components inside rooms

useIsInsideRoom is helpful for rendering different components depending on whether they’re inside a room, or not. One example is a header component that only displays a live avatar stack when users are connected to the room.

Here’s how the example above would render in three different LiveblocksProvider and RoomProvider contexts.

useStatus

Returns the current WebSocket connection status of the room, and will re-render your component whenever it changes.

The possible value are: initial, connecting, connected, reconnecting, or disconnected.

useSyncStatus

Returns the current synchronization status of Liveblocks, and will re-render your component whenever it changes. This includes any part of Liveblocks that may be synchronizing local changes to the server, including (any room’s) Storage, text editors, threads, or notifications.

A { smooth: true } option is also available, which prevents quick changes between states, making it ideal for rendering a synchronization badge in your app.

👉 A Suspense version of this hook is also available.

Display a synchronization badge

Passing { smooth: true } prevents the status changing from "synchronizing" to "synchronized" until 1 second has passed after the final change. This means it’s ideal for rendering a synchronization status badge, as it won’t flicker in a distracting manner when changes are made in quick succession.

Prevent users losing unsaved changes

Liveblocks usually synchronizes milliseconds after a local change, but if a user immediately closes their tab, or if they have a slow connection, it may take longer for changes to synchronize. Enabling preventUnsavedChanges will stop tabs with unsaved changes closing, by opening a dialog that warns users. In usual circumstances, it will very rarely trigger.

More specifically, this option triggers when:

Internally, this option uses the beforeunload event.

useOthersListener

Calls the given callback when an “others” event occurs. Possible event types are:

useLostConnectionListener

Calls the given callback in the exceptional situation that a connection is lost and reconnecting does not happen quickly enough.

This event allows you to build high-quality UIs by warning your users that the app is still trying to re-establish the connection, for example through a toast notification. You may want to take extra care in the mean time to ensure their changes won’t go unsaved.

When this happens, this callback is called with the event lost. Then, once the connection restores, the callback will be called with the value restored. If the connection could definitively not be restored, it will be called with failed (uncommon).

The lostConnectionTimeout client option will determine how quickly this event will fire after a connection loss (default: 5 seconds).

Automatically unsubscribes when the component is unmounted.

For a demonstration of this behavior, see our connection status example.

Presence

Need help troubleshooting presence?

Try the Liveblocks DevTools extension to visualize your collaborative experiences as you build them, in realtime.

useMyPresence

Return the presence of the current user, and a function to update it. Automatically subscribes to updates to the current user’s presence.

Note that the updateMyPresence setter function is different to the setter function returned by React’s useState hook. Instead, you can pass a partial presence object to updateMyPresence, and any changes will be merged into the current presence. It will not replace the entire presence object.

This is roughly equal to:

updateMyPresence accepts an optional argument to add a new item to the undo/redo stack. See room.history for more information.

useUpdateMyPresence

Returns a setter function to update the current user’s presence.

Use this if you don’t need the current user’s presence in your component, but you need to update it (e.g. live cursor). It’s better to use useUpdateMyPresence because it won’t subscribe your component to get rerendered when the presence updates.

Note that the updateMyPresence setter function is different to the setter function returned by React’s useState hook. Instead, you can pass a partial presence object to updateMyPresence, and any changes will be merged into the current presence. It will not replace the entire presence object.

updateMyPresence accepts an optional argument to add a new item to the undo/redo stack. See room.history for more information.

useSelf

Returns the current user once it is connected to the room, and automatically subscribes to updates to the current user.

The benefit of using a selector is that it will only update your component if that particular selection changes. For full details, see how selectors work.

👉 A Suspense version of this hook is also available, which will never return null.

useOthers

Extracts data from the list of other users currently in the same Room, and automatically subscribes to updates on the selected data. For full details, see how selectors work.

The others argument to the useOthers selector function is an immutable array of Users.

👉 A Suspense version of this hook is also available, which will never return null.

One caveat with this API is that selecting a subset of data for each user quickly becomes tricky. When you want to select and get updates for only a particular subset of each user’s data, we recommend using the useOthersMapped hook instead, which is optimized for this use case.

When called without arguments, returns the user list and updates your component whenever anything in it changes. This might be way more often than you want!

Caution

In production-ready apps, you likely want to avoid calling useOthers without arguments.

useOthersMapped

Extract data using a selector for every user in the room, and subscribe to all changes to the selected data. A Suspense version of this hook is also available.

The key difference with useOthers is that the selector (and the optional comparison function) work at the item level, like doing a .map() over the others array.

Returns an array where each item is a pair of [connectionId, data]. For pragmatic reasons, the results are keyed by the connectionId, because in most cases you’ll want to iterate over the results and draw some UI for each, which in React requires you to use a key={connectionId} prop.

useOthersConnectionIds

Returns an array of connection IDs (numbers), and rerenders automatically when users join or leave. This hook is useful in particular in combination with the useOther (singular) hook, to implement high-frequency rerendering of components for each user in the room, e.g. cursors. See the useOther (singular) documentation below for a full usage example.

Roughly equivalent to:

👉 A Suspense version of this hook is also available.

useOther

Extract data using a selector for one specific user in the room, and subscribe to all changes to the selected data. A Suspense version of this hook is also available.

The reason this hook exists is to enable the most efficient rerendering model for high-frequency updates to other’s presences, which is the following structure:

  1. Makes sure this whole component tree will never rerender beyond the first time.
  2. Makes sure the parent component only rerenders when users join/leave.
  3. Makes sure each cursor remains associated to the same connection.
  4. Makes sure each cursor rerenders whenever its data changes only.

👉 A Suspense version of this hook is also available, which will never return null.

Broadcast useBroadcastEvent

Returns a callback that lets you broadcast custom events to other users in the room.

useEventListener

Listen to custom events sent by other people in the room via useBroadcastEvent. Provides the event along with the connectionId of the user that sent the message. If an event was sent from the Broadcast to a room REST API, connectionId will be -1.

The user property will indicate which User instance sent the message. This will typically be equal to one of the others in the room, but it can also be null in case this event was broadcasted from the server, using the Broadcast Event API.

Automatically unsubscribes when the component is unmounted.

Storage

Each room contains Storage, a conflict-free data store that multiple users can edit at the same time. When users make edits simultaneously, conflicts are resolved automatically, and each user will see the same state. Storage is ideal for storing permanent document state, such as shapes on a canvas, notes on a whiteboard, or cells in a spreadsheet.

Data structures

Storage provides three different conflict-free data structures, which you can use to build your application. All structures are permanent and persist when all users have left the room, unlike Presence which is temporary.

Typing Storage

To type the Storage values you receive, make sure to set your Storage type.

You can then set an initial value in RoomProvider.

The type received in your Storage will match the type passed. Learn more under typing your data.

useStorage will return an immutable copy of the data, for example a LiveList is converted to an array, which makes it easy to render.

Nesting data structures

All Storage data structures can be nested, allowing you to create complex trees of conflict-free data.

Here’s an example of setting initialStorage for this type.

useStorage

Extracts data from Liveblocks Storage state and automatically subscribes to updates to that selected data. For full details, see how selectors work.

The root argument to the useStorage selector function is an immutable copy of your entire Liveblocks Storage tree. Think of it as the value you provided in the initialStorage prop at the RoomProvider level, but then (recursively) converted to their “normal” JavaScript equivalents (objects, arrays, maps) that are read-only.

From that immutable root, you can select or compute any value you like. Your component will automatically get rerendered if the value you return differs from the last rendered value.

This hook returns null while storage is still loading. To avoid that, use the Suspense version.

Avoiding unnecessary rerenders

It’s recommended to select only the subset of Storage data that your component needs. This will avoid unnecessary rerenders that happen with overselection.

useHistory

Returns the room’s history. See Room.history for more information.

useUndo

Returns a function that undoes the last operation executed by the current client. It does not impact operations made by other clients.

useRedo

Returns a function that redoes the last operation executed by the current client. It does not impact operations made by other clients.

useCanUndo

Returns whether there are any operations to undo.

useCanRedo

Returns whether there are any operations to redo.

useMutation

Creates a callback function that lets you mutate Liveblocks state.

To make the example above more flexible and work with any color, you have two options:

  1. Close over a local variable and adding it to the dependency array, or
  2. Have it take an extra callback parameter.

Both are equally fine, just a matter of preference.

With dependency arrays

Tip! Let ESLint check your dependencies

If you use ESLint, we recommend to configure it to enforce the correct use of your dependency arrays.

With extra callback parameters

Alternatively, you can add extra parameters to your callback function:

Depending on current presence

For convenience, the mutation context also receives self and others arguments, which are immutable values reflecting the current Presence state, in case your mutation depends on it.

For example, here’s a mutation that will delete all the shapes selected by the current user.

Mutations are automatically batched, so when using useMutation there’s no need to use useBatch, or call room.batch() manually.

ESLint rule

If you are using ESLint in your project, and are using the React hooks plugin, we recommend to add a check for "additional hooks", so that it will also check the dependency arrays of your useMutation calls:

Comments useThreads

Returns a paginated list of threads within the current room. Initially fetches the latest 50 threads.

Use the Thread component to render the latest 50 threads with our default UI.

Querying threads

It’s possible to return threads that match a certain query with the query option. You can filter threads based on their resolved status, and metadata. Additionally, you can filter for metadata strings that being with certain characters using startsWith. Returned threads match the entire query.

Pagination

By default, the useThreads hook returns up to 50 threads. To fetch more, the hook provides additional fields for pagination, similar to useInboxNotifications.

Pagination example

The following example demonstrates how to use the fetchMore function to implement a “Load More” button, which fetches additional threads when clicked. The button is disabled while fetching is in progress.

Error handling

Error handling is another important aspect to consider when using the useThreads hook. The error and fetchMoreError fields provide information about any errors that occurred during the initial fetch or subsequent fetch operations, respectively. You can use these fields to display appropriate error messages to the user and implement retry mechanisms if needed.

The following example shows how to display error messages for both initial loading errors and errors that occur when fetching more threads.

Avoid scrolling to a comment

By default, scrollOnLoad, is enabled. This options scrolls to a comment if the URL’s hash is set to a comment ID (e.g. https://example.com/my-room#cm_nNJs9sb...), the page will scroll to that comment once the threads are loaded. To avoid scrolling to a comment, set scrollOnLoad to false.

👉 A Suspense version of this hook is also available, which will never return a loading state and will throw error to the nearest ErrorBoundary if initial load failed.

useCreateThread

Returns a function that creates a thread with an initial comment, and optionally some metadata.

useDeleteThread

Returns a function that deletes a thread and all its associated comments by ID. Only the thread creator can delete the thread.

useEditThreadMetadata

Returns a function that edits a thread’s metadata.

Deleting properties

To delete an existing metadata property, set its value to null. Passing undefined for a metadata property will ignore it.

useMarkThreadAsResolved

Returns a function that marks a thread as resolved.

useMarkThreadAsUnresolved

Returns a function that marks a thread as unresolved.

useMarkThreadAsRead

Returns a function that marks a thread as read.

useThreadSubscription

Returns the subscription status of a thread, methods to update it, and when the thread was last read. The subscription status affects whether the current user receives inbox notifications when new comments are posted.

subscribe and unsubscribe work similarly to useSubscribeToThread and useUnsubscribeFromThread, but they only affect the current thread.

useSubscribeToThread

Returns a function that subscribes the current user to a thread, meaning they will receive inbox notifications when new comments are posted.

Subscribing will replace any existing subscription for the current thread set at room-level. This value can also be overridden by a room-level call that is run afterwards.

useUnsubscribeFromThread

Returns a function that unsubscribes the current user from a thread, meaning they will no longer receive inbox notifications when new comments are posted.

Unsubscribing will replace any existing subscription for the current thread set at room-level. This value can also be overridden by a room-level call that is run afterwards.

useCreateComment

Returns a function that adds a comment to a thread.

useEditComment

Returns a function that edits a comment’s body.

useDeleteComment

Returns a function that deletes a comment. If it is the last non-deleted comment, the thread also gets deleted.

useAddReaction

Returns a function that adds a reaction to a comment. Can be used to create an emoji picker or emoji reactions.

useRemoveReaction

Returns a function that removes a reaction from a comment. Can be used to create an emoji picker or emoji reactions

useAttachmentUrl

Returns a presigned URL for an attachment by its ID.

👉 A Suspense version of this hook is also available, which will never return a loading state and will throw when there’s an error.

Notifications useInboxNotifications

Returns a paginated list of inbox notifications for the current user. Initially fetches the latest 50 items. Inbox notifications are project-based, meaning notifications from outside the current room are received.

Use the InboxNotification component to render the latest 50 inbox notifications with our default UI.

Pagination

By default, the useInboxNotifications hook returns up to 50 notifications. To fetch more, the hook provides additional fields for pagination, similar to useThreads.

Pagination example

The following example demonstrates how to use the fetchMore function to implement a “Load More” button, which fetches additional inbox notifications when clicked. The button is disabled while fetching is in progress.

Error handling

Error handling is another important aspect to consider when using the useInboxNotifications hook. The error and fetchMoreError fields provide information about any errors that occurred during the initial fetch or subsequent fetch operations, respectively. You can use these fields to display appropriate error messages to the user and implement retry mechanisms if needed.

The following example shows how to display error messages for both initial loading errors and errors that occur when fetching more inbox notifications.

👉 A Suspense version of this hook is also available, which will never return a loading state and will throw error to the nearest ErrorBoundary if initial load failed.

useUnreadInboxNotificationsCount

Returns the number of unread inbox notifications for the current user.

👉 A Suspense version of this hook is also available, which will never return a loading state and will throw when there’s an error.

useMarkInboxNotificationAsRead

Returns a function that marks an inbox notification as read for the current user.

useMarkAllInboxNotificationsAsRead

Returns a function that marks all of the current user‘s inbox notifications as read.

useDeleteInboxNotification

Returns a function that deletes an inbox notification for the current user.

useDeleteAllInboxNotifications

Returns a function that deletes all of the current user‘s inbox notifications.

useInboxNotificationThread

Returns the thread associated with a "thread" inbox notification.

It can only be called with IDs of "thread" inbox notifications, so we recommend only using it when customizing the rendering or in other situations where you can guarantee the kind of the notification.

No fetching and waterfalls

When useInboxNotifications returns "thread" inbox notifications, it also receives the associated threads and caches them behind the scenes. When you call useInboxNotificationThread, it simply returns the cached thread for the inbox notification ID you passed to it, without any fetching or waterfalls.

useRoomSubscriptionSettings

Returns the user’s subscription settings for the current room and a function to update them. Updating this setting will change which inboxNotifications the current user receives in the current room.

For "threads", these are the three possible values that can be set:

For "textMentions", these are the two possible values that can be set:

useUpdateRoomSubscriptionSettings

Returns a function that updates the user’s notification settings for the current room. Updating this setting will change which inboxNotifications the current user receives in the current room.

For "threads", these are the three possible values that can be set:

For "textMentions", these are the two possible values that can be set:

Works the same as updateSettings in useRoomSubscriptionSettings.

Replacing individual thread subscriptions

Subscribing will replace any existing thread subscriptions in the current room. This value can also be overridden by a room-level call that is run afterwards.

useNotificationSettings

Notification settings is currently in beta.

Returns the user’s notification settings in the current project, in other words which notification webhook events will be sent for the current user. Notification settings are project-based, which means that settings and updateSettings are for the current user’s settings in every room. Useful for creating a notification settings panel.

A user’s initial settings are set in the dashboard, and different kinds should be enabled there. If no kind is enabled on the current channel, null will be returned. For example, with the email channel:

Updating notification settings

The updateSettings function can be used to update the current user’s notification settings, changing their settings for every room in the project. Each notification kind must first be enabled on your project’s notification dashboard page before settings can be used.

Subscribing will replace any existing thread subscriptions in the current room. This value can also be overridden by a room-level call that is run afterwards.

Error handling

Error handling is an important aspect to consider when using the useNotificationSettings hook. The error fields provides information about any error that occurred during the fetch operation.

The following example shows how to display error messages for both initial loading errors and errors that occur when fetching more inbox notifications.

👉 A Suspense version of this hook is also available, which will never return a loading state and will throw and error to the nearest ErrorBoundary if initial load failed.

useUpdateNotificationSettings

Notification settings is currently in beta.

Returns a function that updates user’s notification settings, which affects which notification webhook events will be sent for the current user. Notification settings are project-based, which means that updateSettings modifies the current user’s settings in every room. Each notification kind must first be enabled on your project’s notification dashboard page before settings can be used. Useful for creating a notification settings panel.

Works the same as updateSettings in useNotificationSettings. You can pass a partial object, or many settings at once.

Version History

Private beta

Version history is currently in private beta. If you would like access to the beta, please contact us. We’d love to hear from you.

useHistoryVersions

Returns the versions of the room. See Version History Components for more information on how to display versions.

Miscellaneous useUser

Returns user info from a given user ID.

👉 A Suspense version of this hook is also available, which will never return a loading state and will throw when there’s an error.

Providing a resolver function

To use useUser, you should provide a resolver function to the resolveUsers option in createClient.

useRoomInfo

Returns room info from a given room ID.

👉 A Suspense version of this hook is also available, which will never return a loading state and will throw when there’s an error.

TypeScript Typing your data

It’s possible to have automatic types flow through your application by defining a global Liveblocks interface. We recommend doing this in a liveblocks.config.ts file in the root of your app, so it’s easy to keep track of your types. Each type (Presence, Storage, etc.), is optional, but it’s recommended to make use of them.

Here are some example values that might be used.

Typing with createRoomContext

Before Liveblocks 2.0, it was recommended to create your hooks using createRoomContext, and manually pass your types to this function. This is no longer the recommended method for setting up Liveblocks, but it can still be helpful, for example you can use createRoomContext multiple times to create different room types, each with their own correctly typed hooks.

To upgrade to Liveblocks 2.0 and the new typing system, follow the 2.0 migration guide.

Helpers shallow

Compares two values shallowly. This can be used as the second argument to selector based functions to loosen the equality check:

The default way selector results are compared is by checking referential equality (===). If your selector returns computed arrays (like in the example above) or objects, this will not work.

By passing shallow as the second argument, you can “loosen” this check. This is because shallow will shallowly compare the members of an array (or values in an object):

Please note that this will only do a shallow (one level deep) check. Hence the name. If you need to do an arbitrarily deep equality check, you’ll have to write a custom equality function or use a library like Lodash for that.

How selectors work

The concepts and behaviors described in this section apply to all of our selector hooks: useStorage , useSelf , useOthers , useOthersMapped, and useOther (singular).

Examples are illustrated via useStorage

In this section, useStorage is used as the canonical example. This is for illustration purposes only. The described concepts and behaviors apply equally to the other selector hooks.

In a nutshell, the key behaviors for all selector APIs are:

Let’s go over these traits and responsibilities in the next few sections.

Selectors receive immutable data

The received input to all selector functions is a read-only and immutable top level context value that differs for each hook:

For example, suppose you have set up Storage in the typical way by setting initialStorage in your RoomProvider to a tree that describes your app’s data model using LiveList, LiveObject, and LiveMap. The "root" argument for your selector function, however, will receive an immutable and read-only representation of that Storage tree, consisting of "normal" JavaScript datastructures. This makes consumption much easier.

Internally, these read-only trees use a technique called structural sharing. This means that between rerenders, if nodes in the tree did not change, they will guarantee to return the same memory instance. Selecting and returning these nodes directly is therefore safe and considered a good practice, because they are stable references by design.

Selectors return arbitrary values

Selectors you write can return any value. You can use it to “just” select nodes from the root tree (first two examples above), but you can also return computed values, like in the last two examples.

Selector functions must return a stable result

One important rule is that selector functions must return a stable result to be efficient. This means calling the same selector twice with the same argument should return two results that are referentially equal. Special care needs to be taken when filtering or mapping over arrays, or when returning object literals, because those operations create new array or object instances on every call (the reason why is detailed in the next section).

Examples of stable results
(root) => root.animals is stable

Liveblocks guarantees this. All nodes in the Storage tree are stable references as long as their contents don’t change.

️️⚠️ (root) => root.animals.map(...) is not stable

Because .map() creates a new array instance every time. You’ll need to use shallow here.

(root) => root.animals.map(...).join(", ") is stable

Because .join() ultimately returns a string and all primitive values are always stable.

Use a shallow comparison if the result isn’t stable

If your selector function doesn’t return a stable result, it will lead to an explosion of unnecessary rerenders. In most cases, you can use a shallow comparison function to loosen the check:

If your selector function constructs complex objects, then a shallow comparison may not suffice. In those advanced cases, you can provide your own custom comparison function, or use _.isEqual from Lodash.

Selectors auto-subscribe to updates

Selectors effectively automatically subscribe your components to updates to the selected or computed values. This means that your component will automatically rerender when the selected value changes.

Using multiple selector hooks within a single React component is perfectly fine. Each such hook will individually listen for data changes. The component will rerender if at least one of the hooks requires it. If more than one selector returns a new value, the component still only rerenders once.

Technically, deciding if a rerender is needed works by re-running your selector function (root) => root.child every time something changes inside Liveblocks storage. Anywhere. That happens often in a busy multiplayer app! The reason why this is still no problem is that even though root will be a different value on every change, root.child will not be if it didn’t change (due to how Liveblocks internally uses structural sharing).

Only once the returned value is different from the previously returned value, the component will get rerendered. Otherwise, your component will just remain idle.

Consider the case:

And the following timeline:

Deprecated useStorageStatus

Deprecated

This is no longer supported. Starting with 2.12, we recommend using useSyncStatus instead for tracking sync status, because it will reflect sync status of all parts of Liveblocks, not just Storage.

Returns the current storage status of the room, and will re-render your component whenever it changes. A { smooth: true } option is also available, which prevents quick changes between states, making it ideal for rendering a synchronization badge in your app.

👉 A Suspense version of this hook is also available.

useBatch

Deprecated

This is no longer supported. Starting with 0.18, we recommend using useMutation for writing to Storage, which will automatically batch all mutations.

Returns a function that batches Storage and Presence modifications made during the given function. Each modification is grouped together, which means that other clients receive the changes as a single message after the batch function has run. Every modification made during the batch is merged into a single history item (undo/redo).

Note that batch cannot take an async function.

useRoomNotificationSettings

Deprecated

This hook was renamed to [useRoomSubscriptionSettings][] in 2.24 and removed in 3.0, read more in our migration guide.

Returns the user’s subscription settings for the current room and a function to update them. Updating this setting will change which inboxNotifications the current user receives in the current room.

useUpdateRoomNotificationSettings

Deprecated

This hook was renamed to [useUpdateRoomSubscriptionSettings][] in 2.24 and removed in 3.0, read more in our migration guide.

Returns a function that updates the user’s subscription settings for the current room. Updating this setting will change which inboxNotifications the current user receives in the current room.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4