Your newsletter platform can tell you how many people opened issue 42 and which links they clicked. It cannot tell you what that reader did once they landed on your site. That gap is closed with two tools and a UTM naming scheme, not one.
Your newsletter platform and your site analytics answer different questions, and neither substitutes for the other. Substack, Beehiiv, ConvertKit/Kit, Mailchimp and Ghost all report opens, clicks and subscriber growth natively — that data never leaves their dashboards. A cookieless site tool like GhostMetrics has zero visibility into your inbox; it only sees a visit once a tagged link lands someone on your domain. (GhostMetrics has no connection to Ghost, the publishing platform — the name overlap is coincidental.)
utm_source=newsletter, utm_medium=email, and a per-issue utm_campaign — GhostMetrics reads and stores exactly those three parameters.sessionStorage for that browser tab, cleared when the tab closes — there's no returning-reader concept and no cross-session join.data-gm-event and grouping the raw event export by utm_campaign gets you a per-issue conversion count.Everything below assumes you already send a newsletter from somewhere and just want to see what happens after readers click.
The mistake most teams make is looking for one dashboard that shows "newsletter performance" end to end. It doesn't exist, because the two halves of that journey happen in systems that can't see each other. Substack, Beehiiv, ConvertKit/Kit, Mailchimp and Ghost all measure the email itself — who opened it, who clicked which link, how the subscriber list is growing — natively, inside their own dashboards. That's genuinely useful data, and none of it is something a site-analytics tool can see or should try to duplicate.
The moment a reader clicks a link and their browser requests a page on your domain, you've crossed into the second layer. Your newsletter platform's job ends at the click; it has no code running on your website and no way to know what the reader did next. That's the job of whatever site analytics tool you run — GhostMetrics or otherwise. It sees the pageview, the UTM parameters attached to the link that brought them there, and anything that happens on your pages after.
So the honest model is: measure the newsletter in the newsletter tool, measure what readers do on your site with UTMs and a site analytics tool. Trying to force one tool to do both jobs is how teams end up either flying blind on-site or missing open/click data entirely. Treat them as two separate, complementary reports, not one merged number.
A common mistake here is assuming the newsletter platform's own click count and your site's visit count for the same link should match exactly. They won't, and that's not a bug in either tool. Your newsletter tool counts a click when the tracking link is requested — which includes requests that never become a page view, such as security scanners and mail clients that fetch links on the recipient's behalf. Your site analytics tool only counts a pageview once a browser actually renders the page and the tracking script runs. Treat the ESP's click number as "how many times this link was activated" and your site tool's visit number as "how many of those turned into an actual page load" — a gap between them is normal, not evidence that a tool is under-counting.
UTM parameters are just query-string tags appended to a URL that tell the receiving analytics tool where a visit came from. For newsletters, three of the five standard parameters do all the useful work, and picking a consistent scheme up front saves you from a UTM Breakdown table full of one-off values you can't compare.
| Parameter | What it means | Recommended value | Stored by GhostMetrics |
|---|---|---|---|
| utm_source | Where the click originated | newsletter (keep it constant) | Yes |
| utm_medium | The channel type | email (keep it constant) | Yes |
| utm_campaign | Which specific issue sent the click | A unique slug per issue, e.g. issue-42 | Yes |
| utm_term | Paid-search keyword (not a newsletter fit) | Skip it | No |
| utm_content | Distinguishes multiple links to the same page in one send (e.g. header link vs. footer link) | Optional — only worth setting if another tool in your stack reads it | No |
Keep utm_source and utm_medium identical on every link in every issue — the panel groups by the full source / medium / campaign combination, so identical source and medium values are what keep issues comparable line by line instead of scattered across near-duplicate rows. The only value that should change issue to issue is utm_campaign. Use something you can read at a glance six months from now: a sequential number (issue-42) or a short topic slug (pricing-guide-issue) both work; "September newsletter" repeated across four different sends does not, because it collapses four issues into one indistinguishable row. GhostMetrics reads and stores exactly utm_source, utm_medium and utm_campaign — utm_term and utm_content are not stored, so there's no reason to spend time tagging them unless another tool in your stack (like your ESP's own click reports) uses them.
Before you build anything, it helps to know which tool you'd actually check for a given question. Here's the honest split, using GhostMetrics as the site-analytics example — the same logic applies whichever cookieless tool you run.
| Question | Where to look |
|---|---|
| How many people opened issue 42? | Your newsletter platform |
| Which link in the issue got the most clicks? | Your newsletter platform |
| Which pages did those clickers visit on my site? | GhostMetrics — raw export, pageview rows grouped by utm_campaign |
| Did they click my signup or buy button once they arrived? | GhostMetrics — raw export, custom-event rows grouped by utm_campaign |
| How much revenue did the signup generate? | Your payment system — GhostMetrics events have no revenue or value field |
| Did the same reader come back from a later issue? | Neither — no cross-session or returning-visitor view |
Those last two rows aren't a knock on any single tool — they're the honest boundary of what UTM-based, cookieless attribution can do at all. More on exactly why in the limits section below.
It's worth noticing what this table implies about ownership, too. Nobody but you can join these rows together — no tool automatically stitches your ESP's open count to your site's visit count to your signup count into a single funnel. That join happens in a spreadsheet, by you, matching campaign slugs across two dashboards. It's a small amount of manual work per issue, but it's the honest price of not handing a single vendor your entire subscriber-to-customer journey. If that manual step is a dealbreaker, the alternative is a heavier, cookie-based stack that tracks a persistent identity across both the email and the site — a real trade-off, not a free upgrade.
<script defer> tag in your site's <head> is enough for GhostMetrics; it has nothing to do with where your newsletter is sent from.https://acmehq.com/blog/pricing-guide?utm_source=newsletter&utm_medium=email&utm_campaign=issue-42
sessionStorage for the rest of the session.<button type="button" data-gm-event="newsletter-signup-cta">Start your free trial</button>
Prefer to fire it from code instead? window.ghostmetrics.track('newsletter-signup-cta', { section: 'pricing' }) works the same way, with section stored as metadata.utm_campaign. Because events carry the session's UTM data automatically, this needs no extra wiring beyond the attribute or the track() call. More on the two approaches in tracking custom events without Google Analytics.utm_campaign value for the next issue, and each send gets its own row in UTM Breakdown. Custom Events stays a per-event-name total, so the per-issue conversion count always comes from the raw export grouped by utm_campaign. UTM Breakdown shows the top 20 combinations for the period you have selected, so older issues drop off the panel as newer ones outrank them — the export keeps every row.It's worth being upfront about the limits, because "UTMs plus a cookieless tool" is a real answer to newsletter attribution, not a complete one. The boundaries below apply to GhostMetrics specifically but reflect how session-based, cookieless attribution works in general.
Sessions are scoped to one browser tab. GhostMetrics sets no cookies and assigns no visitor ID. The UTM values from a tagged link live in that tab's sessionStorage only, and they're gone the moment the tab closes. Open the same newsletter link tomorrow, or in a different tab, and it's treated as a brand-new session, attributed fresh from whatever link brought that visit in. There is no "returning reader" concept by design — if you need to know whether the same person opened issues 41 and 42, this stack won't tell you.
There's no open or click data on the email itself. GhostMetrics never sees your inbox, your subscriber list, or which specific reader clicked which link — that information lives entirely inside your newsletter platform. Nothing here replaces checking Substack's, Beehiiv's, ConvertKit/Kit's, Mailchimp's or Ghost's own reporting for open rates and click-through rates; it picks up only after the click lands on your domain.
Custom events have no revenue or value field. You can count how many tagged clicks happened per campaign, but there's no built-in way to attach a dollar amount to a conversion or build a multi-step funnel across separate sessions. "Issue 42 drove N signup-button clicks" is a number GhostMetrics gives you cleanly. "Issue 42 drove X in revenue" requires pulling that figure from wherever the actual transaction happened and matching it up yourself.
Taken together, these boundaries mean this setup is genuinely good at "which issues drive site visits and which visits take the action I care about" — a UTM Breakdown row for the issue next to its custom-event rows in the export, both keyed by the same campaign slug, answers that cleanly. It's the wrong tool for "build a lifetime-value model of subscribers acquired through email" or "prove this specific reader converted three issues later." Those questions need a persistent identifier joining email and site behavior over time, which is precisely the tracking model a cookieless, session-scoped tool deliberately doesn't do.
This trips people up because it feels like a dead end, but it isn't — you don't need script access on the newsletter platform at all. Substack does not allow custom scripts on a substack.com publication. For Beehiiv, ConvertKit/Kit and Mailchimp hosted pages, check whether your plan allows custom code. Ghost is the exception: its Admin → Settings → Code injection panel lets you paste a script into the site header on both Ghost(Pro) and self-hosted Ghost, no theme edit required.
None of that actually matters for the setup in this guide, though, because the tracking script was never going in the newsletter platform in the first place — it goes on your own website, the destination the tagged links point to. Whether Substack lets you inject a script into your publication page is irrelevant to whether you can see what happens after someone clicks through to your blog, your pricing page, or your product. Tag the links, install the script on your domain, and the newsletter platform's script policy stops being a blocker.
The one thing you genuinely lose on a locked-down publication host is in-email behavior — scroll depth on the newsletter issue itself, or click heatmaps inside the email — but that was never something a site analytics tool could see anyway, script or no script. It stays with whatever your newsletter platform reports natively.
GhostMetrics reads utm_source, utm_medium and utm_campaign off the landing URL and shows them in a UTM Breakdown table — no cookies, no visitor IDs, session data cleared when the tab closes. The free plan is free forever: one site, unlimited pageviews, real-time dashboard, full history. Custom events work two ways — a declarative data-gm-event attribute on any element, or window.ghostmetrics.track('name', { section: 'pricing' }) from code — and raw event export as CSV or JSON is available on every plan, including free.
Need more than one site, or a public shareable dashboard for a client or stakeholder? Pro is $9.99/mo flat, unlimited pageviews, unlimited websites (fair-use ceiling of 250), with a 30-day free trial — a card starts the trial, nothing is charged for 30 days, cancel anytime.
Start free — one script tag See the live demoDisclosure: GhostMetrics is built by Null Agency and we use it on this site, so we're not a neutral party about our own product — the claims here are limited to what it actually stores, and the limits of UTM-based, cookieless attribution apply to our own tool too. Newsletter platform features and plan permissions vary and change over time; always check your provider's current documentation before assuming what your plan allows.