Crossdeck University
Watch — attach context once, not on every event Film in production
0:00 / 0:00
Lesson 2 of 5 · Analytics

Super properties & groups

Some context belongs on every event — plan tier, app version. And some users belong to a shared entity — an org, a team. Attach both once, instead of on every track() call.

4 min Web

When you're done: you can break down every event by plan, version, or org without passing those on each call.

1 What this is & why it matters

Attach context once, get it on everything

You'll often want to slice every event by the same dimension — "show me this funnel for Pro users only," or "compare app version 2.3 against 2.2." Passing plan and app_version into every single track() call by hand is tedious and easy to forget. Super properties let you register that context once and have it ride along on every future event automatically.

Groups solve the related problem of shared entities: when many users belong to the same org or team, you tag them as members once, and then you can break analytics down by org — seats, expansion, account-level retention — not just by individual.

2 How to set them

register() for properties, group() for entities

Super properties — register them once (usually right after identify()), and they attach to every subsequent event:

// sticks to every event from here on
Crossdeck.register({ plan: "pro", app_version: "2.3.1" });

// drop one when it no longer applies
Crossdeck.unregister("plan");

Groups — tie the current user to a named entity, optionally with traits:

Crossdeck.group("org", "acme_inc");
Crossdeck.group("team", "design", { headcount: 12 });
3 How it works, piece by piece

Right tool, right job

register() stores the properties on the device and merges them into every future event — so it's the right tool for slow-moving context: plan tier, org ID, app version, cohort. It's the wrong tool for per-event data (the amount of a specific purchase, the name of the button clicked) — that belongs in the track() properties for that one event. unregister() removes a super property the moment it stops being true, like when a user downgrades.

group() attaches the user to a named entity, carried on events as $groups. That's what lets the dashboard answer account-level questions — which orgs are expanding, which teams churned — instead of only per-person ones. Both super properties and groups ride along on the same enrichment step as everything else, and as always, a property you pass directly into a track() call wins on a key collision.

4 The green result in your dashboard

Break down by plan or org — for free

With plan registered and org set, every breakdown gains those dimensions automatically. Filter a funnel to Pro, compare retention across app versions, or roll a metric up by org — without having touched a single track() call to add them.

app.cross-deck.com · breakdowns
plan · org · version

Every event now carries plan and app_version, and members of acme_inc roll up by org — set once, present everywhere.

Crossdeck.register({ … }) attaches slow-moving context (plan, version, cohort) to every future event; unregister(key) drops it. Crossdeck.group(type, id, traits?) ties a user to an org or team so you can break analytics down by account. Per-event data still belongs in track() properties.