UTM & Ads parameters

Lightweight Analytics automatically captures UTM tags on the landing page and stores them with the session. No extra configuration needed – just append the standard query parameters to your campaign links.

Supported parameters (parsed by the tracking script):

  • utm_source – required. Examples: newsletter, twitter, google.
  • utm_medium – cpc, email, social, banner …
  • utm_campaign – launch, black-friday, spring-sale …

utm_term & utm_content are ignored for now – we plan to add them later.

Example link:

https://yourapp.com/?utm_source=newsletter&utm_medium=email&utm_campaign=may-launch

When a visitor arrives:

  1. The tracking script reads the query string.
  2. utmSource, utmMedium, and utmCampaign fields are attached to the page-view JSON.
  3. The Cloudflare Worker forwards them to the queue and database.
  4. Dashboard groups the visit under Referrers → Campaigns.

If the visitor browses to more pages, subsequent page-views do not need the parameters – the session is already classified.

Dashboard widgets

  • Campaigns table – compares visitors, page-views, conversions, revenue per (source+medium+campaign) combination.
  • Clicking a row filters the entire dashboard to that campaign, so you can see top pages or countries just for that traffic slice.

Combine with Goals to measure ROI – e.g. % of newsletter visitors that finish signup.

Limitations & tips

First hit only – UTMs are captured on the landing page; internal links must preserve them if you want cross-page attribution.

Hash-based SPAs – if your framework updates the query string without a full reload, call analytics.track('_page') manually after the pushState to record the new virtual page.

Twitter/Mastodon stripping – create a short redirect like /go/twitter → full UTM URL to keep parameters intact.