Crossdeck University
Watch — the dozen events that make the dashboard come alive Film in production
0:00 / 0:00
Lesson 1 of 5 · Analytics

Track custom events

The SDK captures the basics the moment you install it. The dashboard comes alive when you fire the dozen events that describe your business — signup, trial, paywall, churn signal.

5 min Web

When you're done: your own domain events appear on the People timeline and feed every breakdown.

1 What this is & why it matters

Auto-capture answers "is anyone there?" — your events answer "are they doing the thing?"

From the moment you call init(), Crossdeck captures page.viewed, session.started, element.clicked, Web Vitals, and network timing for free. That tells you someone's there. The dashboard becomes genuinely useful — retention, revenue attribution, the journey — the moment you start firing the handful of events that describe what matters in your product: a trial started, a paywall shown, a feature used, a churn signal.

You don't need hundreds. A dozen well-named domain events is the difference between "people visited" and "here's exactly where they convert and where they leak."

2 How to fire one

track(name, properties)

One call. A past-tense, snake_case name, and a flat bag of properties:

Crossdeck.track("trial_started", { plan: "pro", source: "pricing_page" });

Two rules cover naming:

  • Past-tense verb, snake_case. trial_started, not StartTrial. A dotted namespace of your own (billing.invoice_paid) is fine — the dot just groups related events.
  • Reserved prefixes belong to the SDK — never use them: page., session., element., error., webvitals., user., sdk., cd. The auto-tracker owns those; firing one yourself corrupts the captured feed.
3 How it works, piece by piece

You send a name; Crossdeck enriches the rest

On every track(), Crossdeck auto-merges a lot of context you don't have to pass: device info, the sessionId and pageviewId, acquisition data (UTMs, referrer, click IDs), your registered super properties, and any $groups the user belongs to. Your own properties always win on a key collision, so you can override an enriched value when you mean to.

Validation happens right at the SDK boundary — a malformed property is caught at the source, with a clear message, rather than silently disappearing downstream. So when an event lands in the dashboard, you can trust it's shaped the way you sent it. The one thing to avoid: don't hand-fire the reserved events like page.viewed or error.* — the SDK emits those itself, and duplicating them muddies the very breakdowns you're trying to read.

4 The green result in your dashboard

Your events, live on the timeline

Fire trial_started and open the Activity feed or any person's journey — your event is there, named, with its properties and the auto-merged context attached. That's the raw material every breakdown, retention curve, and revenue attribution is built from.

app.cross-deck.com · activity
trial_started · captured

trial_started with plan: pro, source: pricing_page — plus device, session, and acquisition merged in automatically.

Crossdeck.track(name, properties) — past-tense snake_case, never a reserved prefix. The SDK enriches every event with device, session, acquisition, super properties, and groups; your properties win on collision. A dozen good domain events is what makes the whole dashboard worth reading.