Product Analytics for Frontend Engineers
Product Analytics for Frontend EngineersMay 22, 2026

Product Analytics for Frontend Engineers

Using Google Analytics 4, Mixpanel, and Sentry together: what to track, how to avoid duplicate events, and how instrumentation drove a 25% conversion lift and a 35% drop in frontend errors.

Table of Contents

  1. Three Tools, Three Jobs
  2. Event Design
  3. GA4 for Funnels You Can Share
  4. Mixpanel for Product Questions
  5. Sentry for Runtime Truth
  6. Privacy and Performance

Three Tools, Three Jobs {#roles}

We used analytics as a product loop, not a tag dump.

ToolQuestion it answers
GA4Are we acquiring and converting?
MixpanelWhich features get used, by whom, in what order?
SentryWhat is breaking, how often, and on which release?

After wiring these to the new storefront we saw about a 25% conversion increase, 15% lower bounce rate, and 35% fewer frontend errors once Sentry issues were triaged weekly.

Event Design {#events}

Name events as verbs a PM can read. Properties should be stable.

type ShopEvent =
  | { name: 'product_viewed'; properties: { sku: string; category: string } }
  | { name: 'add_to_cart'; properties: { sku: string; value: number } }
  | { name: 'checkout_started'; properties: { itemCount: number; value: number } }
  | { name: 'purchase_completed'; properties: { orderId: string; value: number } };

export function track(event: ShopEvent) {
  mixpanel.track(event.name, event.properties);
  gtag('event', event.name, event.properties);
}

Do not fire page_view from both the router and GA's enhanced measurement without a plan. Duplicate pageviews wreck bounce rate.

Keep a tracking plan in the repo:

| Event | Trigger | Properties | Owner |
| add_to_cart | click CTA | sku, value | Checkout |

If it is not in the plan, it does not ship.

GA4 for Funnels You Can Share {#ga4}

GA4 is the language marketing already speaks. Send purchase with value and currency so revenue reports are not a second spreadsheet.

gtag('event', 'purchase', {
  transaction_id: order.id,
  value: order.total,
  currency: 'USD',
  items: order.lines.map((line) => ({
    item_id: line.sku,
    item_name: line.name,
    price: line.price,
    quantity: line.qty,
  })),
});

Mark checkout steps as a funnel: view_item → add_to_cart → begin_checkout → purchase. When conversion moved 25%, this funnel showed where, not just that the homepage was prettier.

Mixpanel for Product Questions {#mixpanel}

Mixpanel is for "do returning patients use the reorder flow?" and "does the new lab-results tab get a second session?"

mixpanel.identify(user.id);
mixpanel.people.set({
  plan: user.plan,
  lab_count: user.labCount,
});

mixpanel.track('results_tab_opened', {
  panel: 'hormones',
  source: 'email',
});

Cohorts beat vanity: users who opened results twice in 7 days vs. one-and-done. That is how we decided which nav item deserved the expensive redesign.

Sentry for Runtime Truth {#sentry}

Analytics without error tracking celebrates a checkout that throws after the click.

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  tracesSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
  environment: process.env.NEXT_PUBLIC_ENV,
});

Sentry.setUser({ id: user.id });

Tag releases with the git SHA. When error rate dropped 35%, it was not magic: we had a weekly triage of new issues, ownership, and a budget to fix the top five.

Filter noise:

  • Browser extensions
  • Network aborts on route change
  • Third-party scripts you do not control (still track volume, do not page at 2am)

Privacy and Performance {#privacy}

  • Load tags after consent
  • Never send PHI in event properties (medical catalog makes this easy to get wrong)
  • Hash emails if you must join systems
  • Defer analytics chunks so they do not steal LCP

Frontend engineers own the event stream. If Mixpanel is empty and Sentry is noisy, the product is flying blind. Instrument the funnel, then read it every week.