Skip to content

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.

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() 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();
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());

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>;
}

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.