Resources/Developer & SDK/Track custom events

Track custom events

Send your own events from code with Spectry.track(), including e-commerce events.

Custom events let you record any meaningful action — a button click, a signup, a purchase — beyond automatic page views.

Spectry.track()

Spectry.track('subscribed', {
  plan: 'pro',
  price: 29,
  currency: 'USD',
});

The first argument is the event name; the second is an optional object of properties. Properties can be strings, numbers or booleans.

Events are only sent after analytics consent is granted. If there's no consent the call is silently dropped — events are not queued and replayed later, because buffering would mean writing to storage before consent. Don't fire a purchase event from a page that runs before your banner is answered.

E-commerce events

For revenue reporting and checkout funnels, send standard commerce events:

Spectry.track('begin_checkout', { value: 120, currency: 'USD' });
Spectry.track('add_to_cart',   { product_id: 'SKU1', price: 40, quantity: 1 });
Spectry.track('purchase',      { order_total: 120, currency: 'USD', items: 3 });

Revenue reporting reads the order_total property of the purchase event — that exact name, on that exact event. Any other property (including value) is stored and visible on the event, but is not counted as revenue. Sending order_total and currency on purchase enables revenue, AOV and purchase counts in funnel results.

Cart value for targeting

Separately from events, tell Spectry the visitor's current cart total so optin display rules and the {{cart_total}} merge tag can use it:

Spectry.setCartValue(129.90, 'EUR');

Call it whenever the cart changes. The value is kept for the session — so an exit-intent popup two pages later still sees it — and is stored locally only; this call sends nothing to the server.

Form & multi-step events

Spectry.track('field_error', { field_name: 'email', error: 'invalid' });
Spectry.track('form_step_completed', { step_index: 2, completion_rate: 0.66 });

These power AI insights such as form-abandonment detection.

Properties or context?

Properties describe the event. Context describes the visitor. Getting the split right is what stops you repeating the same fields on every call.

Say your app knows the signed-in user is on the pro plan with a business account. That is visitor state, not part of the purchase, so set it once:

Spectry.setContext({ plan: 'pro', account_type: 'business' });

// later, anywhere in the app
Spectry.track('purchase', { order_total: 49, currency: 'EUR' });

The purchase is stored with order_total and currency and with plan and account_type attached, so a segment like "purchases over €100 from visitors on the pro plan" works without plan ever appearing in a track() call. Without context you would have to pass plan on every event, and any call that forgot it would silently fall out of the segment.

A rule of thumb: if you would have to send the same value on more than one kind of event, it is context. See Event context and variables.

Naming events

Event names are matched exactly, so decide on a convention before you scatter track() calls across a codebase. snake_case, present tense, no site or page prefix — signup_completed, not Homepage - Signup Completed!. Renaming an event later doesn't rewrite history: you get two events, and every funnel built on the old name quietly stops counting.

No-code alternative

Prefer not to write code? Use the no-code event builder to define events from CSS selectors, scroll depth or time on page.

Where events appear

Tracked events show up under Events for your site and in dashboard widgets, grouped by the name you passed to Spectry.track().

The funnel step and A/B test goal pickers list the events you defined on the Events page. To make a code-tracked event selectable there, add it once with How is it tracked? → From your code and give it the same key you pass to Spectry.track(). Nothing else is needed: there is no selector to configure, and the properties stay whatever your call sends.

The key has to match character for character. Spectry.track('purchase') and a definition named Purchase are two different events, and the goal built on the second will never convert.

Defining the event changes nothing about capture — events already sent under that key stay exactly as they were, and segments could always filter on them by name and by property.


Put this to work on your own site.

Heatmaps, session replays, funnels and experiments in one platform. Set it up in minutes, no credit card needed, and 5,000 sessions a month are free forever.