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.
1. The page
Section titled “1. The page”<!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>2. Votes in KV
Section titled “2. Votes in KV”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.
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; }), );}3. Who’s here
Section titled “3. Who’s here”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(", ")}`;});4. Publish and share
Section titled “4. Publish and share”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.
Going further
Section titled “Going further”- 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.