Members, sharing and notifications
Members
Section titled “Members”interface MaypopMember { id: string; username: string; role: string; avatarUrl: string | null; connected: boolean;}
interface MaypopMemberList { members: MaypopMember[]; guestCount: number;}
members(): Promise<MaypopMemberList>;members() returns everyone with access to the app — people it is shared
with directly and through groups — sorted by username. connected means
they had the app open in the last few minutes; guestCount is how many
anonymous visitors have it open. It is a snapshot, so call it again to
refresh. id matches maypop.user.id and KV author values for the same
person.
const { members, guestCount } = await maypop.members();renderFaces( members.filter((m) => m.connected), guestCount,);For live presence while people are in the app, use a multiplayer room.
Deep links and sharing
Section titled “Deep links and sharing”interface MaypopLink { to(path?: string): string; unfurl(url: string): Promise<LinkPreview>;}
share(opts: { path: string; title?: string }): Promise<void>;readonly launchPath: string | null;maypop.link.to("/poll/42") returns a Maypop link that opens your app on
that screen. maypop.share({ path, title }) opens Maypop’s share card for
it. When someone opens the link, the app starts with maypop.launchPath
set to /poll/42 (a hash router picks it up on its own).
copyButton.onclick = () => navigator.clipboard.writeText(maypop.link.to(`/poll/${pollId}`));
shareButton.onclick = () => maypop.share({ path: `/poll/${pollId}`, title: "Vote on dinner" });- Paths must start with
/. Build links withlink.to, never fromlocation, which is a sandboxed frame. - The link doesn’t grant access: whoever opens it gets what the app’s sharing settings allow.
sharefails withmaypop/share-unavailablebefore the app has been published and shared; its message is written for the person, so you can show it.- Label in-app buttons by what they share (“Share this poll”). Maypop’s own
Sharebutton already shares the whole app.
link.unfurl(url) fetches a public web page’s title, description and image
on Maypop’s side, for link previews the browser couldn’t fetch itself:
interface LinkPreview { url: string; title?: string; description?: string; image?: string; siteName?: string; favicon?: string;}Notifications
Section titled “Notifications”notify(opts: { to: "all" | string[]; title: string; body?: string; path?: string;}): Promise<void>;Notifications appear in the Maypop bell and, for people who turned them on,
as push notifications on their devices. to: "all" reaches everyone with
access except the sender; otherwise pass member ids. path opens the app on
that screen when tapped.
await maypop.notify({ to: "all", title: "Poll closes in an hour", body: "Dinner on Friday: pizza or tacos?", path: `/poll/${pollId}`,});| Limit | Value |
|---|---|
title |
1–120 characters |
body |
up to 500 characters |
path |
up to 512 characters |
| Recipients | up to 256 ids per call |
| Per app | 30 an hour, in bursts of up to 10 |
| Per person | 5 an hour from one app |
Over the limit, the call rejects with an error whose message is
rate_limited. People who muted the app are skipped silently. Sending needs
use access or more.
Open another app
Section titled “Open another app”apps: { open(id: string): Promise<void> };maypop.apps.open(appId) asks Maypop to open another app. It fails with
maypop/app-not-found when the person can’t open it, and with
maypop/unsupported where there is no Maypop shell around the app.