Skip to main content
This page documents @whop/elements@1.0.0-beta.0 and @whop/elements-react@1.0.0-beta.0.
Pre-release, not yet part of a stable release. Mounts inside Ads. Create it to get a handle, then mount its elements on that handle. Call destroy() to remove the sub-controller. Create it again to get a fresh handle.

Preview

A live, interactive demo of this sub-controller’s default arrangement with example data:

Options

Pass these to ads.create('reporting', { … }), or as props on <Reporting> in React. Parent-injected props never appear here.
"today" | "yesterday" | "last_7_days" | "last_14_days" | "last_30_days" | "last_90_days" | "all_time" | "custom"
The window every surface reports on: today, yesterday, last_7_days, last_14_days, last_30_days, last_90_days, all_time, or custom (pair it with customRange). The chart carries the picker, and it moves this — so a host can drive the window and read it back off periodChanged. Defaults to "last_14_days".
{ from: string; to: string; } | null
The explicit window, as ISO 8601 instants, used when period is custom. Ignored otherwise. Defaults to null.
"account" | "local"
Timezone choice for every reported figure. Use account for the account’s preferences.ads_scheduling_timezone or local for the viewer’s browser timezone. These are the only choices the chart offers. A free-form IANA timezone could make the picker label data incorrectly and would be lost when the viewer changes the selection. To report in another timezone, change the account setting. account falls back to the viewer’s timezone when the account has no setting. Defaults to "account".
string
Lowercase three-letter ISO 4217 currency code for converted amounts, such as usd or eur. Unset, it defaults to the account’s preferences.ads_reporting_currency. Defaults to "".
"last_touch" | "first_touch"
Which touch in a buyer’s journey gets the credit: last_touch, the default, or first_touch. Under both, a Whop touch anywhere in the journey wins the Whop bucket — the model only picks the endpoints. The table carries the picker and moves this, so a host can drive it and read it back off attributionModelChanged. Defaults to "last_touch".
string[]
Narrow reporting to these ad campaigns (adcamp_…). Empty reports on the whole account. Overridden by adGroupIds or adIds when either is set. Pass one ID for an exact figure: the reporting API scopes by a single source path, so where more than one is given the chart reports on the first alone. Defaults to [].
string[]
Narrow reporting to these ad groups (adgrp_…). Takes precedence over campaignIds. Same single-ID caveat. Defaults to [].
string[]
Narrow reporting to these ads (ad_…). The narrowest filter — takes precedence over both others. Same single-ID caveat. Defaults to [].
"ads" | "all" | "campaigns" | "ad-groups"
Which table the table element opens on: campaigns, ad-groups, ads, or all for the traffic-source view. all always reports account-wide — the source series exists only at that level — so a filter set alongside it narrows the table but not the chart. Defaults to "campaigns".
string[] | null
Which traffic the chart reports on, as source paths — whop:* for advertising bought through Whop, ext:* and ext:<platform>:* for ads run elsewhere, referrer:* for organic, direct, other. null, the default, reports on Whop advertising alone; [] reports on every source; a non-empty array reports on those. A DIFFERENT axis to campaignIds and friends, which narrow within Whop advertising — spend-derived ratios stay Whop-attributed whatever this is set to, because spend only ever bought Whop ads. The table element’s All tab moves it. Defaults to null.

Events

Pass callbacks in the create options or React props.

onEditRequested

The viewer asked to edit something — a row menu, a draft row, or Edit ad in the details overlay. campaignId is always there; adGroupId and adId narrow it to what they clicked. Only raised when useCampaignCreator is off; on, the builder opens over the page instead and this stays quiet. Signature: ((payload: AdsEditTarget) => void)

onLoadingChange

Runs when the grouped loading state changes. The value is true while any mounted element is still loading. Signature: ((loading: boolean) => void)

Methods

Call these on the sub handle from ads.create('reporting', { … }).

update

Merges new props and callbacks into the sub-controller. Signature: (options: Partial<ReportingSubOptions>) => void

destroy

Destroys the sub-controller and its elements, then frees its exclusive slot. A later create("reporting") starts fresh. Signature: () => void

Elements

The elements this sub-controller mounts. Each has its own page:

ChartElement

An account’s performance over a window, with a picker for what to plot — spend, impressions, clicks, or any conversion the account records. Read-only.

TableElement

An advertising account’s campaigns, ad groups, and ads in one table, with the tabs that move between them: pick rows to narrow the level below, search, sort, break the numbers down, choose your columns, and pause, resume, duplicate, or delete straight from a row. The window it reports on and the rows it is filtered to live on the handle, so a chart mounted beside it reports on exactly the same thing.

Flow surfaces

These internal elements open automatically during guided flows. They aren’t part of the consumer API, so you don’t mount or configure them.
  • AdDetailsElement (adDetails): A single ad in detail: its creative, its copy, the accounts it runs under, and where it sends people. Opened from a row in the table element — it is not mounted directly, and appears over the page rather than inside either frame.