Goals and revenue
Any event as a goal, pageview and click goals, revenue props, attribution by first exposure.
An event is anything your app sends with track(name, props?). A goal is an event marked as one, and it is what an experiment is judged on. Each experiment names one goal; the verdict is computed on it. Other goals can be read beside it as secondary metrics or guardrails.
Events
const track = useTrack();
track('Video Played', { id: 3 });
One call for every event: React useTrack, client.track in @splithub/core, window.splithub.track with the drop-in script. Any name is recorded; nothing to declare first. Names use letters, digits, spaces and _ . : / -, up to 64 characters. With an analytics property on the provider, every event shows up in its reports; see Analytics.
Goals
Name any event as an experiment's goal (--goal "Video Played" on create) and it is a goal: a name that is not in goals becomes an event goal keyed by its slug (video-played). Declare a goal in the config when you want a label, a value, revenue, a page visit or a click:
goals: {
signup: { type: 'event', name: 'Sign up' },
purchase: { type: 'event', revenue: true },
'video-played': { type: 'event', event: 'Video Played', value: 2 },
pricing_view: { type: 'pageview', path: '/pricing' },
docs_any: { type: 'pageview', path: '/docs/*' },
cta_click: { type: 'click', selector: 'a[href="/start"]' },
}
| Type | Fires when |
|---|---|
event |
your code calls track('signup'), or track('Video Played') for a goal with event: 'Video Played' |
pageview |
a page with that path is viewed; * suffix matches a prefix |
click |
an element matching the selector is clicked; bound automatically by the SDK and the script |
A click goal is sent as a goal when the element is clicked; raw clicks are not recorded as events. name is a label for people, value is what one conversion is worth in analytics reports when the event carries no revenue prop. Goals count as conversions in every analytics property unless the property's goals list narrows them.
Goals can also be made in the dashboard (Settings → Events, the goal switch on an event, or "+ New goal" when creating an experiment) and are delivered to cloud clients. pull does not write goal definitions into the file; add them yourself if you want them there. A goal in use cannot be deleted.
Revenue
track('purchase', { revenue: 49 });
With revenue: true on the goal, results include revenue per variant, and in SplitHub Cloud revenue per visitor (visitors who did not pay count as 0) compared with the control by Welch's t-test. Read it through the API or results --json. The verdict stays on the conversion rate; to make sure a variant that converts more does not earn less, add the revenue goal as a guardrail.
Attribution
A visitor converts for a variant when they sent the goal at or after their first exposure to that experiment. In SplitHub Cloud this is decided at ingest; self-hosted stores apply the same rule when they read. Units are unique visitors: ten purchases by one visitor are one conversion (and the summed revenue). At most 50 of one goal per visitor per day are kept. A goal sent before any exposure counts for nothing, which is the right behavior for "did the change cause it". Earlier goals are not retroactively attributed to a later exposure.
In cloud mode ingest accepts events while the project has a running experiment or property and quota left. Goals from visitors who never saw an experiment do not reach any experiment; an analytics property still records the event.
Props
track(name, props) accepts a flat JSON object up to 4 KB (4,096 characters when JSON-serialized); above that, the SDK keeps what fits, revenue first. revenue is the only key with built-in meaning; the rest is stored with the event and shown in analytics reports, the raw-events view and the CSV export. Keep personal data (emails, names) out of props.
Pageviews in SPAs
The provider sends a pageview on mount, and the client reports every client-side navigation (history and hash routes) as a pageview after that, so pageview goals fire on route changes without extra code. usePageview(path) (React) or client.pageview(path) reports a page by hand, for example when navigation tracking is turned off with trackNavigation: false.
Good goals
- One primary goal per experiment, decided before the experiment starts.
- As close to the change as makes sense: a headline experiment on the home page is judged on "clicked the primary button" or "signed up", not on "paid 30 days later". Put the later outcome in
metrics. - Counts of unique visitors, not of hits. Repeated clicks by one visitor do not make a variant better.