Skip to main content

Tracking Events

The Xaiku SDK provides 12 tracking functions that cover impressions, interactions, conversions, and performance. All functions are available on the sdk.track.events object after initializing @xaiku/browser or @xaiku/react.

Accessing tracking functions

import xaiku from '@xaiku/browser'

const sdk = xaiku({ pkey: 'pk_your_public_key' })

const { events } = sdk.track

Every tracking function accepts an optional extraData object that is merged into the event payload. Common fields to include are experimentId, variantId, and partId for attribution.

Event reference

trackView

Tracks a page or component impression.

events.trackView({ experimentId: 'exp_1', variantId: 'var_a' })
ParameterTypeDescription
extraDataobjectOptional. Merged into the event payload.

Reported event name: impression

trackClick

Tracks a click interaction.

events.trackClick({ experimentId: 'exp_1', variantId: 'var_a', partId: 'cta' })
ParameterTypeDescription
extraDataobjectOptional. Merged into the event payload.

Reported event name: click

trackDwellTime

Measures how long a user spends viewing content. Returns start and stop functions so you control when timing begins and ends.

const timer = events.trackDwellTime({ experimentId: 'exp_1' })

timer.start()

// Later, when the user navigates away or the section leaves viewport:
timer.stop()
ParameterTypeDescription
extraDataobjectOptional. Merged into the event payload.

Calling stop() reports a dwell_time event with a timeOnPage field (milliseconds). Calling stop() before start() is a no-op.

trackScrollDepth

Tracks the maximum scroll percentage reached on the page. Attaches a scroll listener and reports the value on beforeunload.

events.trackScrollDepth({ experimentId: 'exp_1' })
ParameterTypeDescription
extraDataobjectOptional. Merged into the event payload.

Reported event name: scroll_depth. The payload includes scrollDepth (0--100).

trackConversion

Tracks a conversion action such as a form submission, purchase, or sign-up.

events.trackConversion({
experimentId: 'exp_1',
variantId: 'var_a',
value: 49.99,
})
ParameterTypeDescription
extraDataobjectOptional. Merged into the event payload.

Reported event name: conversion

trackTimeToConversion

Records the elapsed time between an initial impression and a later conversion.

const impressionTime = Date.now()

// ... user interacts with the page ...

events.trackTimeToConversion(impressionTime, {
experimentId: 'exp_1',
variantId: 'var_a',
})
ParameterTypeDescription
impressionTimestampnumber | stringTimestamp of the original impression. Parsed with new Date().
extraDataobjectOptional. Merged into the event payload.

Reported event name: time_to_conversion. The payload includes timeToConversion (milliseconds).

trackBounce

Detects if a user leaves the page quickly. A beforeunload listener fires and reports a bounce event if the user spent less than 5 seconds on the page.

events.trackBounce({ experimentId: 'exp_1' })
ParameterTypeDescription
extraDataobjectOptional. Merged into the event payload.

Reported event name: bounce. The payload includes timeOnPage (milliseconds). Only reported when the dwell time is under 5,000 ms.

trackHover

Measures hover duration on a specific DOM element. Attaches mouseenter and mouseleave listeners.

const element = document.getElementById('pricing-card')
events.trackHover(element, { experimentId: 'exp_1' })
ParameterTypeDescription
elementHTMLElementRequired. The DOM element to observe.
extraDataobjectOptional. Merged into the event payload.

Reported event name: hover. The payload includes hoverDuration (milliseconds). A new event is sent each time the user hovers and then leaves the element.

trackFeedback

Captures a user-submitted rating or sentiment score.

events.trackFeedback(4, { experimentId: 'exp_1', comment: 'Great experience' })
ParameterTypeDescription
ratingnumberRequired. The rating value (e.g., 1--5).
extraDataobjectOptional. Merged into the event payload.

Reported event name: feedback. The payload includes rating.

trackPerformanceMetrics

Captures page load timing from the Navigation Timing API.

events.trackPerformanceMetrics({ experimentId: 'exp_1' })
ParameterTypeDescription
extraDataobjectOptional. Merged into the event payload.

Reported event name: performance. The payload includes loadTime (milliseconds from navigationStart to loadEventEnd). Requires window.performance.timing to be available.

trackError

Captures a JavaScript error as an event.

try {
riskyOperation()
} catch (err) {
events.trackError(err, { experimentId: 'exp_1', context: 'checkout' })
}
ParameterTypeDescription
errorErrorRequired. The error object.
extraDataobjectOptional. Merged into the event payload.

Reported event name: error. The payload includes errorMessage and stack.

trackNumericMetric

Records an arbitrary numeric value under a custom metric name. Use this for any measurement not covered by the built-in functions.

events.trackNumericMetric('checkout_items', 3, { experimentId: 'exp_1' })
events.trackNumericMetric('load_time_ms', 842, { page: '/dashboard' })
ParameterTypeDescription
metricNamestringRequired. The name used as the event name.
valuenumberRequired. The numeric value to record.
extraDataobjectOptional. Merged into the event payload.

The metricName becomes the reported event name. The payload includes value.

Event batching

Events are not sent to the API individually. Instead they are buffered and flushed in batches for performance:

  • Batch size: The buffer flushes when it reaches 5 events.
  • Flush interval: A timer flushes the buffer every 5 seconds, even if fewer than 5 events have accumulated.
  • Page unload: On unload, the remaining buffer is sent via navigator.sendBeacon to avoid data loss.

Each flushed event is automatically enriched with client attributes including sessionId, userId, pathname, referrer, userAgent, domain, and any searchParams configured on the SDK.

If test mode is active, every event is tagged with test: true so it can be filtered in analytics.

React hooks

In React, use the tracking hooks instead of calling sdk.track.events directly:

import { useTrackView, useTrackClick, useTrackConversion } from '@xaiku/react'

function PricingCard({ experimentId, variantId }) {
useTrackView({ experimentId, variantId, partId: 'pricing' })

const trackClick = useTrackClick({ experimentId, variantId, partId: 'pricing' })
const trackConversion = useTrackConversion({ experimentId, variantId, partId: 'pricing' })

return (
<div>
<button onClick={trackClick}>Learn More</button>
<button onClick={() => { trackClick(); trackConversion(); }}>
Buy Now
</button>
</div>
)
}

useTrackView fires once per unique combination of experimentId, variantId, and partId. The click and conversion hooks return stable callback functions.

Summary table

FunctionEvent nameKey payload fieldsAuto-listener?
trackViewimpression--No
trackClickclick--No
trackDwellTimedwell_timetimeOnPageNo (manual start/stop)
trackScrollDepthscroll_depthscrollDepthYes (scroll + beforeunload)
trackConversionconversion--No
trackTimeToConversiontime_to_conversiontimeToConversionNo
trackBouncebouncetimeOnPageYes (beforeunload, <5s)
trackHoverhoverhoverDurationYes (mouseenter/mouseleave)
trackFeedbackfeedbackratingNo
trackPerformanceMetricsperformanceloadTimeNo
trackErrorerrorerrorMessage, stackNo
trackNumericMetriccustomvalueNo

Next steps