Flock
Examples

Who's Online

A minimal "who's viewing this page" widget using usePresence().

This example shows a row of colored avatar circles for every user currently on the page. It uses usePresence() and useMyPresence() and is under 50 lines of application code.

The apps/demo-presence app in the monorepo is a standalone Next.js app with this exact widget. View on GitHub.

The widget

// ViewerWidget.tsx
"use client";
 
import { usePresence, useMyPresence } from "@xevrion/flock-react";
 
function initials(name: string) {
  return name.split(" ").map((w) => w[0]).join("").toUpperCase().slice(0, 2);
}
 
export function ViewerWidget() {
  const others = usePresence();
  const [me] = useMyPresence();
 
  const all = [
    { userId: "me", metadata: { ...me, name: (me.name ?? "You") + " (you)" } },
    ...others,
  ];
 
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
      <span style={{ fontSize: 13, color: "#888" }}>
        {others.length + 1} viewing
      </span>
      <div style={{ display: "flex" }}>
        {all.map((user, i) => (
          <div
            key={user.userId}
            title={user.metadata.name as string}
            style={{
              width: 32,
              height: 32,
              borderRadius: "50%",
              background: user.metadata.color as string ?? "#444",
              border: "2px solid #000",
              marginLeft: i === 0 ? 0 : -8,
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              color: "#fff",
              fontSize: 12,
              fontWeight: 700,
              position: "relative",
              zIndex: all.length - i,
            }}
          >
            {initials((user.metadata.name as string) ?? user.userId)}
          </div>
        ))}
      </div>
    </div>
  );
}

Wiring it up

// page.tsx
import { FlockProvider } from "@xevrion/flock-react";
import { ViewerWidget } from "./ViewerWidget";
 
export default function Page() {
  return (
    <FlockProvider
      serverUrl={process.env.NEXT_PUBLIC_FLOCK_SERVER_URL!}
      roomId="my-page"
      userId={yourUserId}
      metadata={{ name: yourName, color: yourColor }}
    >
      <ViewerWidget />
      {/* rest of your page */}
    </FlockProvider>
  );
}

Key patterns

  • Local user first: the widget includes yourself using useMyPresence(), so the count always shows "1 viewing" even when alone, not "0 viewing."
  • usePresence() excludes you: others only contains other users. We prepend ourselves from useMyPresence() to build the full all list.
  • Overlapping avatars: marginLeft: -8 overlaps the circles. zIndex: all.length - i ensures the first avatar (you) is on top.
  • Initials fallback: if no avatar image is available, show the user's initials derived from their name.

See also

On this page