analytics

why

analytics is the product's memory of what visitors actually did; its value exists only when each fact is attributable to a question someone reads. the invariant is signal density: every event answers a named question in domain vocabulary and has an owner. unowned interaction tracking buries answerable signals in noise, trains the team to ignore dashboards, and leaves product decisions running on intuition. a small question-driven event set keeps evidence cheap to collect and direct to act on.

rule

an analytics event is a structured, durable fact about product use — the same discipline as structured logging for the internal product. every event answers a named product question, uses domain glossary vocabulary, and has an owner who reads the answer.

an event without an answerable question is noise: decisions run on incomplete data, success/failure gets attributed to the wrong signals, and unread events pile up and train the team to ignore analytics. metrics without questions are waste disguised as instrumentation.

event design

propertystandard
namestable domain phrase: onboarding.fvm.reached, run.started.
fieldsglossary nouns with typed values (workflowId, surface, outcome).
questionthe named question it answers, recorded where events are declared.
identitycorrelation id when the event spans an operation.
privacyno secret payloads, no unclassified content, per privacy and content ownership.

instrument at the boundary that owns the fact — the route, the workflow boundary, the mutation — not sprinkled through components.

the question set

design the event set from the product questions, written down:

questionevents
do visitors reach the first valuable moment?arrival, each onboarding step, FVM reached.
where do they abandon?step exits with the step name.
which capabilities are used?operation-level invoked events.
do workflows succeed for people?workflow started/completed/failed (already in metrics and alerts).
do changes help?the before/after of the question the change addressed.

do not

  • instrument everything instrumentable; instrument the question set.
  • send PII or unclassified content in event payloads.
  • track third-party script events with different names for the same fact.
  • keep an event whose question nobody can state.
  • ship a change without recording which question it moves, when it has one.

verification

list the question set and its events. every declared event maps to a question; every question's dashboard/answer can be read today. fire each event once through its owning boundary in a non-production environment and confirm name, fields, and vocabulary match the declaration.

good and bad

bad

track("button_clicked", { color: "blue", page: location.pathname });
track("input_focused", { fieldName: "email" });
track("form_submitted", { page: location.pathname, timestamp: now() });

these events track every interaction without naming what they answer. when form_submitted counts rise, there is no baseline question: engagement up? repeated submission retries? completions up or just attempts? the event becomes noise; the team stops reading dashboards and decides on intuition.

good

// question: do visitors reach the first valuable moment?
track("workflow.started", { workflowId, surface: WorkflowSurfaceEnum.Editor });
// question: where do users abandon?
track("workflow.setup_skipped", { connectionRequired: true });
// question: do workflows succeed for people?
track("workflow.completed", { workflowId, durationSeconds, itemCount });

each event names its question, uses domain vocabulary, and has a declared owner (the product lead managing onboarding or success metrics) who reads the dashboard. the team tracks "completion rate" not just "form_submitted", so metric attribution is direct and actionable.

search pages

go to any page