Upcoming — generated from the latest merged element source; documents unreleased development. Use the channel picker at the top of the sidebar for the docs of a published release.
Playground
Assemble the elements with sample data — drive the controls, add and arrange elements, and watch events fire live:Usage
Options
Pass these towhop.websites.create({ … }) — or as props on <Websites> in React.
number
How many days of traffic the table covers, from 1 to 90. @default 30 Defaults to
30.boolean
List websites built on whop.app from the moment they exist, with zeros until traffic arrives. Turn off to show only domains the pixel reports. @default true Defaults to
true.PendingWebsite[]
Websites you have just added that are not live yet —
{ domain, kind }, where kind is deploy for a whop.app site waiting on its first deploy or events for a site waiting on its first pixel events. They render as waiting rows so a site never looks lost right after setup, and the table polls while any is outstanding. Defaults to [].boolean
Add a pixel-check button to each row. The element only reports the press through
onVerifyRequested — opening the site and deciding the outcome is yours, because a popup opened by your own page is the one browsers trust. Defaults to false.boolean
Add a settings button to whop.app rows. The element only reports the press through
onSettingsRequested — the editing surface is yours. Defaults to false.string
Which row the check in progress belongs to — the
target from the verifyRequested event you are handling. Defaults to ""."idle" | "waiting" | "connected" | "not-detected" | "blocked"
How the check in progress is going, shown on that row’s button:
waiting, connected, not-detected, or blocked when the popup was blocked. Defaults to "idle".string
A scoped token for the reads — stats need
stats:read, and the whop.app website list reads apps (rows degrade to traffic-only if the token can’t). Mint it on your server with POST /v1/access_tokens and set a fresh one before it expires. Omitted, the reads carry the viewer’s own session, which only answers same-origin.string
required
The company whose websites these surfaces read —
biz_….Appearance
Visual customization for this group’s elements — overrides the global
WhopElements({ appearance }); change it live with update({ appearance }).WhopElementsLocale
Locale for this group’s element UI text — one of the app’s built locales, overriding the global config; any other value falls back to the default locale.
Events
Pass a callback in the create options / React props.onLoadingChange
Fired when the grouped loading state changes — true while any mounted element is still loading.
Signature: ((loading: boolean) => void)
Methods
Call these on the Websites handle — the return ofwhop.websites.create({ … }) (vanilla) or useWebsites() (React).
update
Update the handle live: any of its options (appearance and locale included), propagated to every mounted element. React consumers never call it — updating the namespace component’s props does the same.
Signature: (options: Partial<WebsitesOptions>) => void
Returned objects
Live objects returned by the methods above — hold the reference and call it on your page; these are capabilities, not serializable data.PendingWebsite
The public surface of PendingWebsite.
domain
Signature: string
kind
Signature: "events" | "deploy"
Elements
The elements this group mounts — each has its own page:WebsitesElement
An account’s websites in one table: every site built on whop.app — listed from the moment it exists, zeros until traffic arrives — merged by hostname with every domain the Whop Pixel reports. Each row shows a page-view trend, unique visitors, page views, and the last day an event arrived. Expanding a domain loads its most-viewed pages, and each page-view figure opens the breakdown of which events made it up. Set
showVerify to add a per-row button that asks the page hosting this element to open the site and confirm the pixel is firing; set showSettings to add a settings button on whop.app rows that reports the click through onSettingsRequested — your page owns the actual editing.
