Skip to content

Track events

Events are how you record what visitors do: signups, checkouts, clicks, scroll milestones. There are two ways to fire them, and they are equivalent. Use whichever fits your codebase.

Events power experiment goals and custom metrics, so name them stably.

Instrument the page with HTML attributes alone, no JavaScript required. This works well for marketing pages and lets non-developers add tracking.

AttributeFires
data-statskit-event="name"an event named name when the element is clicked
data-statskit-scroll="name"an event named name when the element scrolls into view (at least 50% visible)
data-statskit-ignoremarks an element and its subtree as do-not-track (no autocapture inside)
Declarative events
<button data-statskit-event="signup_click">Sign up</button>
<a data-statskit-event="pricing_click" data-statskit-props='{"plan":"pro"}'>Upgrade</a>
<section data-statskit-scroll="reached_pricing"> … pricing … </section>
<div data-statskit-ignore> … nothing in here is auto-captured … </div>

Attach event properties with data-statskit-props, a JSON object string.

Call track anywhere in your JavaScript:

Track an event
window.statskit?.track("signup", { plan: "pro" });

The signature is statskit.track(name, props?). All methods are safe to call before the script finishes loading: a stub queue buffers early calls and drains them on init, so the optional-chaining ?. is belt-and-suspenders.

Pass a value in minor units (cents) so revenue math is exact. A $49.99 checkout is 4999:

Conversion value
statskit.track("checkout", { value: 4999, plan: "pro" });
Checkout button
function CheckoutButton({ cents }: { cents: number }) {
return (
<button
onClick={() => {
window.statskit?.track("checkout", { value: cents });
startCheckout();
}}
>
Buy now
</button>
);
}
  • Reach for declarative attributes on static markup and for conversions non-developers need to add.
  • Reach for statskit.track when the event fires from application logic (an async success, a computed value, a modal), or when you need a value computed at runtime.

Both produce the same event, so mixing them across a page is fine.