Custom events
What gets captured for free, and how to record the events only your app knows about.
Autocapture sees interactions. Your code sees meaning. The gap between "a
button was clicked" and "a subscription was created" is what customEvent
closes.
Free from the install
With enableAutomaticTracking on (the default), the SDK records page views and
navigation, clicks on buttons and links, form submissions, and the friction
signals derived from that behaviour — rage clicks and unresponsive controls.
Tune what that includes:
HumanBehaviorTracker.init(apiKey, {
automaticTrackingOptions: {
trackButtons: true,
trackLinks: true,
trackForms: true,
includeText: false, // don't record the element's text
includeClasses: false,
},
});includeText: false is worth considering if your button labels can contain
customer data.
Your own events
await tracker.customEvent("subscription_created", {
plan: "pro",
seats: 12,
mrr: 240,
});An event needs a name; properties are optional and are what make it useful
later. plan is why you can ask which plan converts, rather than only how many
conversions there were.
Two rules that decide whether this pays off
One spelling per event. subscription_created everywhere, not
SubscriptionCreated in one component. Nothing downstream merges two spellings,
so you get two half-counts and no warning.
Name the outcome, not the widget. checkout_submitted still means something
after the button moves; blue_button_clicked does not.
Timing
Events raised in the first few seconds of a session are held until the session
passes minimumDurationMilliseconds (default 5000), then flushed together. An
event fired immediately on page load is not lost — it is queued.
Events with an empty or invalid name are skipped with a warning rather than sent.
Where they show up
On Dashboard's event breakdown, as funnel steps, on a person's timeline in Visitors, and to anything asking questions through Home or MCP.
Excluding a property everywhere is propertyDenylist on init.