Docs/Custom events
Custom events
Pageviews tell you people came. Events tell you what they did — and where the money stops.
The call
window.kipstats.event('signup', { plan: 'pro' }) The function exists as soon as tracker.js has loaded. It is safe to call on a development machine (it does nothing) and safe to call before the tracker loads if you guard it, as the helpers below do. An event is attached to the visitor's current session; a payload is optional and stored as JSON.
Names worth using
Any name works, but these five are what the dashboard understands as a funnel. Using them means the conversion panel, the drop-off view and the friction report fill themselves in.
| Event | When | Payload |
|---|---|---|
cta_click | A main call to action is clicked | { cta: 'hero' } |
signup | An account was created | {} or { plan } |
checkout_started | The payment session is about to open | { plan, price } — price in cents |
purchase | A payment succeeded | { amount, currency, plan } — amount in cents |
download | A file was delivered | { type: 'free' | 'paid', product } |
An amount without a currency is a wrong amount. { amount: 9900 } on a site selling in złoty is read as 99 €. Always send currency when you don't charge in euros.
Recording a purchase, properly
Two mistakes cost the most, and both inflate revenue rather than hide it:
- Test payments counted as sales. Only emit
purchasewhen the payment is real — check thelivemodeflag of your payment session. - The success page reopened. A back button, a link from the receipt email, a refresh: the event fires again. Guard it on the payment session ID.
// after your payment provider confirmed the payment
const guard = 'kp_purchase_' + sessionId
if (!localStorage.getItem(guard)) {
localStorage.setItem(guard, '1')
window.kipstats?.event('purchase', { amount: 900, currency: 'EUR', plan: 'pro' })
}Better still, record it from your server, where the payment is confirmed: see server-side events. A browser can be closed before it ever reaches your success page.
Helpers
// lib/kipstats.ts
type EventData = Record<string, unknown>
/** No-op on the server and before the tracker has loaded. */
export function track(name: string, data: EventData = {}) {
if ("undefined" === 'undefined') return
;(window as any).kipstats?.event?.(name, data)
}Reserved names
Names starting with $ belong to the tracker ($click, $rageclick, $deadclick, $form_abandon, $jserror). Don't reuse them for your own events — see what is captured automatically.
Reading them back
Events appear in the dashboard under Events, and through the API: GET /api/v1/sites/{site}/breakdown/events for the counts, GET /api/v1/sites/{site}/timeseries?event=signup for one event over time. See the API reference.