Users
playhtml.users is where you read and set who someone is: their name and color. It works whether or not cursors are enabled.
It helps to keep three things apart. Users is who people are: durable identity that persists across visits. Presence is what they’re doing right now: live, ephemeral channels that clear when they leave. Cursors render both as the pointer and label you see moving around the page.
users.me
Section titled “users.me”Your own identity. Reading it gives you a flat object; writing to its fields persists the change and publishes it to everyone else in the room.
playhtml.users.me.name; // "Alice"
playhtml.users.me.color; // "#3b82f6"
playhtml.users.me.pid; // a stable per-user id
// Persist and publish a new name
playhtml.users.me.name = "Bob";
// Persist and publish a new color (also updates your cursor, if cursors are enabled)
playhtml.users.me.color = "#ff0000";
When cursors are enabled, window.cursors.color and window.cursors.name are aliases for these fields (see Cursors). playhtml.users is the primary API and does not require cursors.
getAll() and onChange()
Section titled “getAll() and onChange()”getAll() returns an array of everyone currently in the room, including yourself, flagged with isMe. This works without cursors enabled.
for (const user of playhtml.users.getAll()) {
user.pid; // string, stable per-user id
user.name; // string | undefined
user.color; // string
user.isMe; // boolean
}
onChange(callback) subscribes to join, leave, and identity changes (yours or anyone else’s) and returns an unsubscribe function:
const unsubscribe = playhtml.users.onChange((users) => {
console.log(`${users.length} people here`);
});
// Later
unsubscribe();
Example: a live roster
Section titled “Example: a live roster”function renderRoster(users) {
const list = document.querySelector("#roster");
list.innerHTML = "";
for (const user of users) {
const item = document.createElement("li");
item.textContent = user.name ?? "anonymous";
item.style.color = user.color;
list.appendChild(item);
}
}
playhtml.users.onChange(renderRoster);
renderRoster(playhtml.users.getAll()); import { useUsers } from "@playhtml/react";
function Roster() {
const users = useUsers();
return (
<ul>
{users.map((user) => (
<li key={user.pid} style={{ color: user.color }}>
{user.name ?? "anonymous"}
</li>
))}
</ul>
);
} useUsers()
Section titled “useUsers()”Reactive version of getAll(). Re-renders your component whenever someone joins, leaves, or changes their identity.
import { useUsers } from "@playhtml/react";
function OnlineCount() {
const users = useUsers();
return <div>{users.length} online</div>;
}
usePlayerIdentity()
Section titled “usePlayerIdentity()”Reads your own identity reactively. It does not require cursors to be enabled.
import { usePlayerIdentity } from "@playhtml/react";
function Profile() {
const { color, pid, name } = usePlayerIdentity();
return <div style={{ color }}>{name ?? "anonymous"}</div>;
}
See the React API reference for full signatures.