A measurement plan before a single tag
Why a written measurement plan beats another layer of tags: the event dictionary this site uses to instrument itself, and how to draft your own in an hour.
Sample entry (track P-B). Replaces with the real launch article from the Phase 1 content sprint (P-D).
Most tracking debt starts the same way: someone opens the tag manager before anyone has written down what a conversion actually is. This site went the other way — every event it measures existed in a table before a line of JavaScript did.
The event dictionary
The whole site is instrumented from one dictionary. Each row answers three questions: what happened, what context travels with it, and who consumes it downstream.
| Event | Parameters | Consumer |
|---|---|---|
page_view |
page_type, hub |
session receipt |
scroll_50 |
page_type |
read-depth |
cta_click |
location, target |
session receipt |
rage_click |
selector, count |
easter egg |
From dictionary to dataLayer
The dictionary compiles to a typed push helper, so an event that is not in the plan cannot ship:
type SiteEvent = | { event: 'page_view'; page_type: string; hub?: string } | { event: 'cta_click'; location: string; target: string };
export function track(payload: SiteEvent) { // v1: local only — nothing leaves the browser (see /colophon). console.debug('[instrumented]', payload);}Why this order matters
- Naming arguments happen once, in a document — not forever, in production.
- The plan is the QA checklist: every row is a testable assertion.
- When a stakeholder asks “can we track X?”, the answer is a diff, not a dig.
Start with ten rows. You can always add an eleventh — deleting a shipped tag is the part that never happens.