Show active user presence (like Google Docs or Figma) with Remix
From the dawn of the internet, we've had hit counters on websites to see how many people visited. Over time, those fell out of fashion, but now they're back in a new form: presence indicators.
- Blogs and news sites tell you how many other users are actively reading the same article.
- Ecommerce sites show you how many other users are looking at the same product.
- Web apps like Google Docs and Figma show you who else is viewing or editing the same document. Sometimes you can even see their cursor position.
Try out a live example of what we're building
With Remix, these are easy to set up. In this guide, we will
- Create a form with an emoji picker
- Use a cookie session storage to save the user's name and emoji.
- Create a full stack component to control the presence widget.
- Use event streams to update the presence widget in real time.
Setting your name and avatar
If you're retrofitting this into a system where you already have user accounts and images, you can skip this section.
Start with a simple form that with a text input for the name, a set of radio buttons for the emoji, and a submit button.
tsx
<Form method="post"> <input aria-label="Name" id="name" name="name" type="text" placeholder="Display name" defaultValue={self.name} className="block w-full border-none bg-transparent px-4 py-3 text-lg placeholder:text-gray-400 focus:shadow-none focus:outline-none focus:ring-0" required /> <div className="flex flex-wrap"> {/* Basic avatar with initial of name when there's no emoji selected */} <label className="flex items-center justify-center"> <input type="radio" name="emoji" value="" defaultChecked={!self.emoji} className="peer h-0 w-0 opacity-0" /> <span className="flex h-14 w-14 items-center justify-center rounded-full border-4 border-transparent bg-white p-2 text-3xl font-medium text-black focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2 peer-checked:border-indigo-600"> A </span> </label> {["😀", "😆", "😍", "😎", "🥸", "