Skip to content

Tutorial: a live group poll

This tutorial builds a poll in one HTML file. Votes are saved in the KV store and update live for everyone; a multiplayer room shows who’s looking right now.

<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Dinner poll</title>
<script src="https://api.app.maypop.ai/sdk/v1.js"></script>
</head>
<body>
<h1>Where should we eat?</h1>
<p id="online"></p>
<ul id="options"></ul>
<script type="module" src="./poll.js"></script>
</body>
</html>

Each person’s vote is its own key, vote/<their id>, so two people voting at once never collide. Subscribing re-renders whenever anyone votes.

poll.js
const OPTIONS = ["Pizza", "Tacos", "Ramen"];
await maypop.ready();
const me = maypop.user.id;
let votes = [];
maypop.kv.subscribe("vote/", (entries) => {
votes = entries.map((e) => e.value);
render();
});
async function vote(option) {
if (maypop.mode !== "read-write") {
if (maypop.signInRequired) maypop.signIn();
return;
}
await maypop.kv.set(`vote/${me}`, option);
}
function render() {
const list = document.getElementById("options");
list.replaceChildren(
...OPTIONS.map((option) => {
const count = votes.filter((v) => v === option).length;
const button = document.createElement("button");
button.textContent = `${option} — ${count}`;
button.onclick = () => vote(option);
const item = document.createElement("li");
item.append(button);
return item;
}),
);
}

Join a room and show everyone’s name. Presence needs no storage: it lives only while people have the app open.

const room = await maypop.multiplayer.join("poll");
room.subscribe((r) => {
const names = r.peers.map((p) => (p.self ? "you" : p.username));
document.getElementById("online").textContent =
`Here now: ${names.join(", ")}`;
});

Publish the folder with the CLI (framework = "static"), or paste the code into a new app in Studio and ask it to keep it as-is. Then share it with Can use, or put it in a group.

  • Let people propose options: store them under option/ and subscribe.
  • Notify everyone when the poll closes with maypop.notify.
  • Keep votes secret until the end with a saved-data policy.