Client: Presence
Track who’s online in a room, listen for join/leave events, and share ephemeral presence state (like "typing"
or "away"
).
Need user-level presence across tabs or devices? Use the createPresence utility to group connections by user ID or any other logic.
Subscribing
Subscribe to presence in a room:
const { success, present } = await client.subscribePresence(
"lobby",
(update) => {
if (update.type === "join") {
console.log("User joined:", update.connectionId);
} else if (update.type === "leave") {
console.log("User left:", update.connectionId);
} else if (update.type === "state") {
console.log("State update:", update.connectionId, update.state);
}
}
);
You’ll receive:
- A list of currently present connection IDs via
present
- Real-time
"join"
,"leave"
, and"state"
events
Unsubscribe when done:
await client.unsubscribePresence("lobby");
Join + subscribe in one step
Use joinRoom()
with a callback to automatically subscribe to presence:
const { success, present } = await client.joinRoom("lobby", (update) => {
console.log(update);
});
If you omit the callback, present
still reflects the current occupants — but you won’t receive real-time updates.
Publishing presence state
Send ephemeral presence state to others in the room:
await client.publishPresenceState("lobby", {
state: { status: "typing" },
expireAfter: 8000, // optional (ms)
});
Clear it manually:
await client.clearPresenceState("lobby");
Automatic presence refresh
The client automatically refreshes presence every 15 seconds for all rooms you’ve joined.
You don’t need to manually track rooms or re-send updates — Mesh handles it behind the scenes.
Receiving presence states
Presence updates include state events:
const { success, present, states } = await client.subscribePresence(
"lobby",
(update) => {
if (update.type === "state") {
console.log(`${update.connectionId} state:`, update.state);
}
}
);
You’ll also get a states
object with current values at the time of subscription:
{
"abc123": { status: "typing" },
"def456": { status: "away" }
}
Resolving user info
Presence events only include connectionId
. To show user names or avatars, fetch metadata:
const metadata = await client.getConnectionMetadata(update.connectionId);
Or resolve metadata for all present connections:
const all = await Promise.all(
present.map((id) => client.getConnectionMetadata(id))
);
// [{ userId, username, avatar }, ...]
Want to show only one presence per user?
→ createPresence
Use cases
- Online indicators
- Room occupancy lists
- Typing indicators
- Game states like “ready”, “spectating”, etc.
Tips
- Unsubscribe when no longer needed to reduce overhead
- Resubscribe after reconnecting
(or usecreatePresence
, which handles this for you) - Use
expireAfter
for short-lived states like"typing"
- Debounce frequent updates to avoid spamming the network