Custom events
Count interactions with track() or a data-motion-event attribute. Cookie-free, SPA-safe.
Count an interaction
Pageviews are recorded for you. A custom event counts anything else that matters: a signup, a plan upgrade, a download, an outbound click. Call track with a name and the event lands on your dashboard alongside pageviews, with its own visitor and total counts.
window.motionAnalytics.track("Signed up")The name is the unit you report on, so keep it stable and human: Signed up, not btn_click_42. Names are trimmed to 120 characters. The call is safe to make before the tracker has loaded only once window.motionAnalytics exists, so guard it if you fire events very early: window.motionAnalytics?.track("Signed up").
Without writing JavaScript
Any element with a data-motion-event attribute fires that event when it is clicked, no script wiring required. Clicks inside the element count too, so wrapping a link or button is enough.
<button data-motion-event="Signed up">Create account</button>The handler is bound in the capture phase, so the event still records even when the click navigates the page away: the beacon is sent with navigator.sendBeacon and survives the unload.
Common recipes
For outbound links and downloads the declarative attribute is usually enough. When you need to wait for something to succeed first, such as a form that can fail validation, call track from your own handler after the success.
// Outbound link
link.addEventListener("click", () =>
window.motionAnalytics.track("Outbound: docs"),
)
// File download
window.motionAnalytics.track("Download: brand-kit.zip")
// Form submit, only after it succeeds
async function onSubmit(e) {
e.preventDefault()
const ok = await submit(form)
if (ok) window.motionAnalytics.track("Signed up")
}Events are cookie-free like everything else: a name and a count, with no per-event properties and no personal data. If you want to slice an event by a value (plan, source), encode it in the name for now, e.g. Upgraded: Pro.