Most collaborative features rely on each user having their own temporary state, which is then shared with others. For example, in an app using multiplayer cursors, the location of each user’s cursor will be their state. This state could also be used for a typing indicator, or to show a user’s current selection. In Liveblocks, we call this presence.
We can use presence to hold any object that we wish to share with others. An example would be the coordinates of a user’s cursor on screen:
cursor: { x: 256, y: 367 }
To start using presence, let’s define a type for it in liveblocks.config.ts
.
We’ll use the format above for displaying cursors, with the addition of null
to represent an off-screen cursor.
/liveblocks.config.ts
// Presence typePresence: { cursor: { x: number; y: number } | null;};
When using TypeScript, all types defined within this file are automatically propagated into function and properties in each Liveblocks package.
The last step in setting up presence is setting an initial value. Switch to
App.tsx
and pass cursor: null
to RoomProvider
—no one starts with
their cursor on-screen.
/App.tsx
<RoomProvider id={roomId} initialPresence={{ cursor: null }}>
To display the current user’s presence, we’ll add useMyPresence
to
Room.tsx
, and quickly display its value, similarly to useState
.
/Room.tsx
import { useMyPresence } from "@liveblocks/react/suspense";
export function Room() { const [myPresence, updateMyPresence] = useMyPresence();
return <div>Cursor: {JSON.stringify(myPresence.cursor)}</div>;}
Great! Press the refresh button in the preview window to reload
initialPresence
, and you should now be seeing Cursor: null
! On the next page
we’ll be creating live cursors with presence.