Skip to content

Events

An event is a named thing that happened on a session, optionally with a value and some metadata. Fire it from JavaScript or declare it in HTML.

signals('newsletter_signup');
signals('video_play', { title: 'Launch keynote' });
signals('add_to_cart', 4999, { sku: 'SKU-123', qty: 1 });
ArgumentTypeNotes
namestringRequired. The event name as it will appear everywhere: sessions, conversions, the API.
valuestring or numberOptional. Stored as given; numeric values are also indexed as a number so you can filter event_value_num > 10.
metaobjectOptional. Free-form key/value pairs stored with the event.

The second argument is overloaded: if it is an object it is treated as meta and value stays null.

signals('plan_selected', 'pro'); // value only
signals('plan_selected', { plan: 'pro' }); // meta only
signals('plan_selected', 'pro', { seats: 5 }); // both

The call returns a promise resolving to { success: true } or { success: false, error }. It never throws. You do not need to await it unless you want to know it landed.

Events fire only once the tracker has a session. Before that, the call resolves { success: false, error: 'Not initialized' } and logs a warning. For events that can fire during page load, wait first:

await signals.ready;
signals('experiment_bucket', 'B');

Any element with data-signal fires an event without JavaScript.

AttributeMeaning
data-signal="name"The event name. Fires on click by default, using event delegation, so it works on elements added later.
data-signal-value="..."The value. Always sent as a string.
data-signal-meta='{"k":"v"}'JSON metadata. Invalid JSON logs Invalid JSON in data-signal-meta and sends {}.
data-signal-on="visible"Fire once when at least half the element is in the viewport, instead of on click.
data-signal-delay="5000"Fire once after the element has been on the page for N milliseconds.
<section data-signal="pricing_viewed" data-signal-on="visible">...</section>
<div data-signal="engaged_30s" data-signal-delay="30000"></div>
<a href="https://app.snipform.io/register" data-signal="cta_click" data-signal-meta='{"placement":"hero"}'>Start</a>

visible and delay elements fire at most once per page; the tracker remembers which elements have fired. Click elements fire on every click. An element with data-signal-on="visible" does not also fire on click.

visible and delay elements are scanned at DOM ready and again after each client-side navigation. Elements you inject later with data-signal-on="visible" are not observed until the next navigation; use signals() for those.

Names are free text, but they are the key you will filter on and build conversion steps from, so pick a convention and keep it:

  • snake_case, lower case: add_to_cart, not Add To Cart.
  • Verb-noun or noun-verb, consistently: video_play, video_complete.
  • Put the variable part in value or meta, not the name: plan_selected with value pro, not plan_selected_pro.
  • Session drawer in the dashboard: every event in order, with value and meta.
  • Conversions: a step with trigger type event trips when a session has an event with that name, optionally matching a value. See Steps & Triggers.
  • Automations: the “An event fires” trigger runs actions the moment the event lands. See Triggers & Conditions.
  • API and SDK: filter sessions by event_name, event_value and event_value_num, for example event_name:purchase event_value_num:>100. See the field catalog.

A page is not always the right place to record what happened: an order is confirmed by your server, not by the browser. Carry the session id to your backend and fire the event from there with the API or the PHP SDK. Session Handoff covers getting the id across.