GenerateSaaS

Email analytics

Track opens and clicks for marketing emails and read per-template rates on the admin Emails page.

Email analytics measures how your marketing emails perform: who opens them and who clicks. Every founder-style send is tagged, its opens and clicks are recorded, and the numbers roll up into an admin Emails page at /admin/emails with a per-template scorecard and a rate-over-time chart. It is on by default and works with any provider - no vendor dashboard, no external setup.

What gets tracked

Only the five founder-style marketing templates carry tracking:

TemplatePurpose
welcomePost-signup founder hello
announcementProduct announcement
getting-started-check-inOnboarding nudge
feedback-requestAsk for feedback
we-miss-youRe-engagement

Transactional emails are never tracked. Password resets, verifications, magic links, and invitations carry no pixel and no rewritten links - they are functional mail, not campaigns, so they never appear in analytics.

How it works

Each tracked send gets two signed hooks, both served by your own backend:

  • Open: a 1x1 pixel with a signed token. When the mail client loads the image, the backend verifies the signature and records an open.
  • Click: every link is rewritten to a signed redirect. The backend verifies the token, records a click, then 302s the reader to the real destination.

Signing means the counts cannot be forged by replaying a URL. Because both hooks are plain HTTP on your backend, analytics is provider-agnostic - it behaves identically on SMTP, SES, and Resend with zero provider configuration.

The prefetch window

Mailbox providers fetch a message's images and security gateways follow its links as the mail lands, seconds before a human could have seen it. Hits that arrive within 10 seconds of dispatch are therefore ignored: the pixel still returns and tracked links still redirect, but no event is recorded. Without it a single send scores a 100% open rate before the recipient has even looked at their inbox.

Only marketing templates are tracked, so nothing real is lost - nobody reads a re-engagement email ten seconds after it was queued.

Metrics

The same counts drive every card and chart. Rates fall back to 0 when the denominator is 0.

MetricDefinition
SentEmails sent for that template in the selected period.
ViewsTotal opens, repeat opens of the same email included. A count, never a share of sent - one recipient re-reading a mail three times would push a "view rate" past 100%.
Open rateUnique opens / sent. Each recipient counts once, so it never exceeds 100%.
Click rateUnique clicks / sent. Each recipient counts once.
CTORClick-to-open rate: unique clicks / unique opens.

Opens are approximate; clicks are not. The prefetch window drops the fetches that happen at delivery, but mail privacy proxies (Apple Mail Privacy Protection, Gmail's image cache) can also load the pixel minutes later without a human looking, which still inflates views and open rate. A click is a deliberate action a proxy does not fake, so treat click rate as the trustworthy comparison metric when iterating on a template's subject line or copy.

The admin Emails page

/admin/emails has two parts:

  • Per-template cards - one card per tracked template showing sent, views, open rate, click rate, and CTOR for the range.
  • Rate chart - two lines, open rate and click rate, plotted over time. Switch the window with the 7 / 30 / 90 day tabs and narrow to a single template with the template filter.

The page loads the last 90 days once; the period tabs and template filter re-slice that data in the browser, so switching views is instant.

Configuration

Analytics is governed by config.email.tracking in packages/config/src/index.ts:

email: {
  // ...
  tracking: {
    enabled: true,      // default - master switch
    retentionDays: 90   // default - days of event history to keep
  }
}
  • enabled turns the whole feature on or off.
  • retentionDays caps how long open and click events are retained. A daily cleanup job deletes events older than this window.

Setting enabled: false hides the admin Emails page and its nav tab and stops recording new opens and clicks. Links in already-sent emails keep redirecting so readers are never stranded - they simply are not counted.

Privacy

  • No personal identifiers are stored. Events record which send was opened or clicked and when, never the reader's IP address or user agent.
  • Cascade deletion. A user's email events are deleted with the user, so removing an account leaves no analytics trail behind.
  • Retention cleanup. The daily job prunes events past retentionDays, keeping the table bounded and old data out of reach.

Rotating BETTER_AUTH_SECRET invalidates tracking URLs in already-delivered emails - opens stop counting and tracked links stop redirecting, since the destination is signature-verified, like other signed links such as unsubscribe.

On this page