A measurement capability from zero
GA4 and Tag Manager built, tested and live before a relaunch, feeding a dashboard the marketing team opens themselves.
outcome
- Live and verified on day one of the relaunch, with a migration comparison available from launch.
- The five tools went from no measurable signal to individually reportable — including the subscription-carrying ones, whose renewal case now rests on usage rather than assumption.
- In daily use by the marketing team, replacing hours of manual reporting each week at zero recurring cost.
- Measurement infrastructure owned and administered by Marketing rather than borrowed from IT.
The dashboard, on invented numbers
This is the shape of the thing I built, rebuilt on CambiumPak so it can be published. Change the date range and every figure moves. Then switch to default install and watch most of it go dark, which is what analytics gives a manufacturer before anybody does the work.
Every number on this page is invented. It comes from a seeded generator, not from any real site, so the tiles agree with the charts and the parts sum to the whole. CambiumPak is an invented company and this is a portfolio demonstration. The dashboard it stands in for was built for an employer, holds their data, and is not published anywhere.
overview
A relaunch was about to ship five interactive tools — a product configurator, a material comparison tool, a right-size calculator licensed from a third party, a recycled-content credit finder and a redesigned distributor portal. None of them emitted a measurable signal and some carried subscription costs. There was also no view of which documents drove demand, and no way to compare the new site against the old, which a relaunch destroys on launch day unless the migration is planned first.
I audited what existed, moved the tag container to an account Marketing controlled, specified and built six event families by hand with registered custom dimensions, and instrumented three properties on staging before go-live. Then I built the reporting layer on top: a dashboard querying the Analytics Data API directly, so the marketing team opens it themselves rather than waiting on a report.
Four months. No developer, no software budget, no recurring cost.
honest limitation
A majority of early portal login events recorded a blank user type. I found it, documented it as a post-launch fix and flagged it to stakeholders rather than presenting the data as clean. Until it’s fixed that segment is directional, not authoritative.
the audit, and what it found3 findings
- The container was under the wrong account. Provisioned under IT’s account rather than Marketing’s. I created a replacement under the right account, coordinated access with IT, briefed the agency to swap the snippet, and confirmed the old one was removed rather than left firing in parallel.
- The legacy containers were empty. Both held no tags, so the live site ran on hard-coded on-page tracking — which explained why nothing had ever been changeable without a developer.
- Advertising tags were about to be orphaned. Ad platform and social tags hadn’t been carried across to the new build. Flagged pre-launch with a remediation path.
relaunch readiness3 properties
- Three properties configured in parallel — new site, legacy site, distributor portal — so post-launch performance had a baseline to compare against.
- Tracking built and verified on staging before go-live. Tags confirmed firing via preview mode and hit-level inspection, screenshotted and confirmed back to the agency.
- Live on day one, including a cross-property migration comparison.
every event answered a live question6 events
The fifth row is the one worth pausing on. Login volume tells you the portal is busy. Login volume by user type tells you whether it’s reaching distributors or just being used internally.
the tags, built by hand5 builds, 6 events
No auto-events, no plugins. Each one specified, built, tested in preview, verified in hit detail, published, and paired with a registered custom dimension — a parameter that isn’t registered never appears in a report. Five builds cover the six events above, because the interactive-tools tag handles the layout planner and the forms together.
- File downloads. Document type resolved through a RegEx table mapping seven categories, product code extracted via custom JavaScript, so downloads report by what and by which product.
- Product configurator. Event on the request button, element variables reading the generated SKU and a validity attribute — capturing failed configurations too, because failure is a UX signal.
- Comparison tool. Element visibility trigger on the results container, custom JavaScript extracting every compared product plus a count. This feeds the renewal decision directly.
- Interactive tools. Click tags scoped by destination URL, with one form tag scoped to the form’s unique identifier rather than the page, so it doesn’t misfire where the form is embedded in several places.
- Portal logins. Custom JavaScript variable reading user role from a body class, firing a login event with a user-type parameter. An untracked authenticated area became a segmentable audience with no backend work.
two judgment calls2 decisions
- The tracking I chose not to build. The right-size calculator turned out to be a vendor component embed generating non-deterministic element IDs on every render. DOM-based tracking against it would have appeared to work and broken silently on the vendor’s next release. I used the vendor’s own reporting and shipped a page-view metric as the interim measure.
- The discovery that avoided a backend project. Portal login tracking was scoped as API work with an external development partner. Inspecting the post-login page showed the user role was already in the markup, which collapsed it into one variable.
the dashboard, under the hood12 queries
An access-controlled web dashboard querying the Analytics Data API directly. Twelve named report queries, from totals, daily active users and traffic by source and medium to downloads by filename, product page performance, portal logins by user type, form starts versus submissions, and a cross-property migration comparison. Date range selector and PDF export.
- Service account authentication hand-rolled, not lifted from an SDK: constructing and RSA-signing a JWT assertion, exchanging it for an access token, caching that token just under its expiry.
- Two-tier caching — a token cache and a per-date-range payload cache — to stay inside API quota.
- Queries batched in groups of five per request rather than fired individually.
- Least privilege. The service account holds read-only viewer access and nothing else, documented at the top of the file.
- Graceful degradation. Missing configuration returns a clear disabled state with the reason, not an error.
Why custom. Commercial reporting tools were used first. They hit real limits: filters silently dropping between report views, and interface changes that removed controls the team relied on.
architectureend to end
no vendor past the analytics platform · nothing in it needs a developer to change
How this got built
Nine steps in order — the first conversation, the measurement plan, the tags, the QA, and the report that changed a decision. Rebuilt on an invented company so the screens can be shown.
The real dashboard is employer owned and holds company data, so what is playable above is a rebuild of it on an invented company. I can walk through the architecture, the event schema and the QA process in a conversation.
open to marketing operations, analytics and martech roles
Let’s talk.
Remote, or Albuquerque and hybrid. Happy to walk through the architecture behind any of this.