API Reference - @liveblocks/react

React context provider that let you use all the presence and storage hooks of @liveblocks/react.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { createClient } from "@liveblocks/client";
import { LiveblocksProvider } from "@liveblocks/react";
const client = createClient({
authEndpoint: "/api/auth",
});
function AppRoot() {
return (
<LiveblocksProvider client={client}>
{ /* children */ }
</LiveblocksProvider>
);
}

Makes a Room available in the component hierarchy below. When this component is unmounted, the current user leave the room. That means that you can’t have 2 RoomProvider with the same room id in your react tree.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { createClient } from "@liveblocks/client";
import { LiveblocksProvider } from "@liveblocks/react";
const client = createClient({
authEndpoint: "/api/auth",
});
function AppRoot() {
return (
<LiveblocksProvider client={client}>
<RoomProvider id="my-room" defaultPresence={() => ({ cursor: { x: 0, y: 0 }})}>
{ /* children */ }
</RoomProvider>
</LiveblocksProvider>
);
}

Returns the presence of the current user, and a function to update it.
updateMyPresence is different than the setState function returned by the useState hook from React. You don’t need to pass the full presence object to update it.

1
2
3
4
5
6
7
import { useMyPresence } from "@liveblocks/react";
const [myPresence, updateMyPresence] = useMyPresence();
updateMyPresence({ x: 0 });
updateMyPresence({ y: 0 });
// At the next render, "myPresence" will be equal to "{ x: 0, y: 0 }"

useUpdateMyPresence is similar to useMyPresence but it only returns the function to update the current user presence. If you don’t use the current user presence in your component, but you need to update it (e.g. live cursor), it’s better to use useUpdateMyPresence to avoid unnecessary renders.

1
2
3
4
5
import { useUpdateMyPresence } from "@liveblocks/react";
const updateMyPresence = useUpdateMyPresence();
updateMyPresence({ y: 0 });

Returns an object that lets you get information about all the the users currently connected in the room.

1
2
3
4
5
6
7
8
9
10
11
12
13
import { useOthers } from "@liveblocks/react";
const others = useOthers();
// Example to map all cursors in jsx
{
others.map(({ connectionId, presence }) => {
if(presence == null || presence.cursor == null) {
return null;
}
return <Cursor key={connectionId} cursor={presence.cursor} />
})
}

Gets the current user once it is connected to the room.

1
2
3
import { useSelf } from "@liveblocks/react";
const currentUser = useSelf();

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

1
2
3
4
5
import { useBroadcastEvent } from "@liveblocks/react";
const broadcast = useBroadcastEvent();
broadcast({ type: "EMOJI", emoji: "🔥" });

Listen to custom events sent by other people in the room via useBroadcastEvent

1
2
3
4
5
6
7
import { useEventListener } from "@liveblocks/react";
useEventListener(({ connectionId, event }) => {
if (event.type === "EMOJI") {
// Do something
}
});

Listen to potential room connection errors.

1
2
3
4
5
6
7
8
9
import { useErrorListener } from "@liveblocks/react";
useErrorListener(error => {
if (error.code === 4005) {
// Maximum concurrent connections per room exceeded.
} else if (error.code === 4003) {
// Maximum concurrent connections per app exceeded.
}
});

The storage block is in private beta

If we didn’t give you access explicitly, the following APIs will not work. The following APIs are subject to change during the beta.

The room’s storage is a conflicts-free state that multiple users can edit at the same time. It persists even after everyone leaves the room. Liveblocks provides 3 data structures that can be nested to create the state that you want.

  • LiveObject - Similar to JavaScript object. If multiple users update the same property simultaneously, the last modification received by the Liveblocks servers is the winner.
  • LiveList - An ordered collection of items synchronized across clients. Even if multiple users add/remove/move elements simultaneously, LiveList will solve the conflicts to ensure everyone sees the same collection of items.
  • LiveMap - Similar to a JavaScript Map. If multiple users update the same property simultaneously, the last modification received by the Liveblocks servers is the winner.
@liveblocks/react provides a set of hooks that let you interact with the room’s storage.

The data structures are mutable

If we didn’t give you access explicitly, the following APIs will not work. The following APIs are subject to change during the beta.

Returns the LiveObject associated with the provided key. If the LiveObject does not exist, it will be created with the initialData parameter. The hook returns null while the storage is loading. The hook triggers a re-render if the LiveObject is updated, however it does not triggers a re-render if a nested data structure is updated.

Create an empty LiveObject.

1
2
3
import { useObject } from '@liveblocks/react';
const object = useObject("key");

Create a LiveObject with initial data.

1
2
3
import { useObject } from '@liveblocks/react';
const mathematician = useObject("key", { firstName: "Ada", lastName: "Lovelace" });

Returns the LiveMap associated with the provided key. If the LiveMap does not exist, it will be created with the entries parameter. The hook returns null while the storage is loading. The hook triggers a re-render if the LiveMap is updated, however it does not triggers a re-render if a nested data structure is updated.

Create an empty LiveMap.

1
2
3
import { useMap } from '@liveblocks/react';
const emptyMap = useMap("mapA");

Create a LiveMap with initial data.

1
2
3
import { useMap } from '@liveblocks/react';
const mapWithItems = useMap("mapB", [["keyA", "valueA"], ["keyB", "valueB"]]);

Returns the LiveList associated with the provided key. If the LiveList does not exist, it will be created with the items parameter. The hook returns null while the storage is loading. The hook triggers a re-render if the LiveList is updated, however it does not triggers a re-render if a nested data structure is updated.

Create an empty LiveList.

1
2
3
import { useList } from '@liveblocks/react';
const emptyList = useMap("listA");

Create a LiveList with initial data.

1
2
3
import { useList } from '@liveblocks/react';
const animals = useList("animals", ["🦁", "🦊", "🐵"]);