Skip to content

PostHog Analytics

Complete guide for product analytics with PostHog in the Freeze Design webshop.

Status 2026-06-10: PostHog is not receiving events

The PostHog project currently receives no events — the instrumentation is broken/missing. Do not use PostHog to verify errors or traffic until this is fixed; Sentry is the working error tracker. The sections below describe the intended setup and remain valid as reference once instrumentation is restored.

Overview

PostHog provides product analytics, session recording, and feature flags. We use the EU-hosted instance for GDPR compliance.

Feature Status Free Tier
Product Analytics ⚠️ Configured (no events arriving) 1M events/month
Session Recording ⚠️ Configured (no events arriving) 5K recordings/month
Feature Flags ✅ Available Unlimited
A/B Testing ✅ Available Unlimited

Setup

1. Create PostHog Account

  1. Go to eu.posthog.com (EU instance for GDPR)
  2. Sign up with GitHub or email
  3. Create a new project (e.g., "Freeze Design Production")
  4. Copy your Project API Key from Settings → Project → Project API Key

2. Configure Environment

Add to frontend/.env.local:

NEXT_PUBLIC_POSTHOG_KEY=phc_your_project_api_key
NEXT_PUBLIC_POSTHOG_HOST=https://eu.i.posthog.com

For production, add these as secrets in your deployment platform.

3. Verify Installation

  1. Start the frontend: npm run dev
  2. Accept the analytics cookies in the cookie banner (capturing is opt-out by default)
  3. Open browser DevTools → Network tab
  4. Filter by "posthog"
  5. Navigate between pages (non-admin pages — PostHog is not loaded on admin routes)
  6. You should see requests to eu.i.posthog.com

Architecture

┌─────────────────┐     ┌──────────────────┐     ┌─────────────┐
│   layout.tsx    │────▶│ PostHogProvider  │────▶│ posthog.ts  │
│  (root layout)  │     │ (pageview track) │     │  (init/API) │
└─────────────────┘     └──────────────────┘     └─────────────┘
                                               ┌─────────────────┐
                                               │ eu.i.posthog.com│
                                               └─────────────────┘

Admin routes are excluded

app/layout.tsx loads PostHogProvider via a dynamic import and only mounts it in the non-admin branch of the layout. Admin sessions are deliberately kept out of the product analytics (and posthog-js stays out of the admin bundle).

Automatic Tracking

These events are tracked automatically:

Event Trigger Data
$pageview Page navigation URL, referrer
$pageleave Page exit Time on page
$autocapture Clicks, inputs Element info

Custom E-commerce Events

Import and use the e-commerce event helpers:

import { ecommerceEvents } from '@/lib/posthog';

// Product viewed
ecommerceEvents.viewProduct('prod-123', 'T-Shirt Classic', 24.99);

// Added to cart
ecommerceEvents.addToCart('prod-123', 'T-Shirt Classic', 2, 24.99);

// Removed from cart
ecommerceEvents.removeFromCart('prod-123', 'T-Shirt Classic');

// Checkout started
ecommerceEvents.beginCheckout(149.97, 3);

// Order completed
ecommerceEvents.completeCheckout('order-456', 149.97, 3);

// Design created in designer
ecommerceEvents.designCreated('prod-123', 'custom-print');

// Design saved
ecommerceEvents.designSaved('design-789');

Custom Events

Track any custom event:

import { trackEvent } from '@/lib/posthog';

// Track with properties
trackEvent('team_order_created', {
  teamSize: 15,
  productType: 'polo-shirt',
  hasCustomDesign: true,
});

// Track simple event
trackEvent('newsletter_subscribed');

User Identification

Identify logged-in users for cross-session tracking:

import { identifyUser, resetUser } from '@/lib/posthog';

// After login
identifyUser(user.id, {
  email: user.email,
  name: user.name,
  plan: user.subscriptionPlan,
});

// After logout
resetUser();

Feature Flags

Create a Feature Flag

  1. Go to PostHog → Feature Flags
  2. Click "New feature flag"
  3. Set the key (e.g., new-checkout-flow)
  4. Configure rollout percentage or user targeting
  5. Save

Use in Code

import posthog from 'posthog-js';

// Check if feature is enabled
if (posthog.isFeatureEnabled('new-checkout-flow')) {
  // Show new checkout
} else {
  // Show old checkout
}

// Get feature flag value (for multivariate flags)
const variant = posthog.getFeatureFlag('pricing-experiment');
if (variant === 'discount-10') {
  // Show 10% discount
}

React Hook Pattern

import { useFeatureFlagEnabled } from 'posthog-js/react';

function CheckoutButton() {
  const showNewCheckout = useFeatureFlagEnabled('new-checkout-flow');

  if (showNewCheckout) {
    return <NewCheckoutButton />;
  }
  return <LegacyCheckoutButton />;
}

A/B Testing

Create an Experiment

  1. Go to PostHog → Experiments
  2. Click "New experiment"
  3. Set experiment name and feature flag key
  4. Define variants (control, test)
  5. Set goal metric (e.g., order_completed)
  6. Set minimum sample size
  7. Launch experiment

Track Experiment Goal

// The goal event is automatically tracked when you use ecommerceEvents
ecommerceEvents.completeCheckout(orderId, orderValue, itemCount);

// Or track custom goal
trackEvent('experiment_goal_reached', {
  experiment: 'pricing-test',
  variant: 'discount-10',
});

Session Recording

Session recordings are enabled by default. Configure in lib/posthog.ts:

posthog.init(POSTHOG_KEY, {
  // Disable to save quota
  disable_session_recording: false,

  // Mask sensitive data
  mask_all_text: false,  // Set true to mask all text
  mask_all_element_attributes: false,
});

View Recordings

  1. Go to PostHog → Recordings
  2. Filter by:
  3. Page URL
  4. User properties
  5. Events performed
  6. Watch recording to understand user behavior

Dashboard Setup

Create these dashboards in PostHog:

1. E-commerce Funnel

Product Viewed → Added to Cart → Checkout Started → Order Completed
  1. Go to Insights → New insight
  2. Select "Funnel"
  3. Add steps: product_viewed, product_added_to_cart, checkout_started, order_completed
  4. Save to dashboard

2. Key Metrics

Metric Insight Type Event
Daily Active Users Trends $pageview (unique users)
Conversion Rate Funnel Full e-commerce funnel
Avg Order Value Trends order_completed → avg of orderValue
Cart Abandonment Funnel Cart → Checkout drop-off

3. Designer Usage

Track product designer engagement:

  • design_created - New designs started
  • design_saved - Designs saved
  • Time in designer (session recording)

GDPR Compliance

Our PostHog setup is GDPR compliant:

Setting Value Purpose
api_host eu.i.posthog.com EU data residency
respect_dnt true Honor Do Not Track
opt_out_capturing_by_default true No capture before cookie-consent opt-in
property_denylist ['$ip'] Don't store IP addresses
persistence localStorage+cookie User consent controls

The cookie banner is implemented in frontend/components/CookieConsent.tsx. It stores the choice under the cookie_consent key in localStorage; lib/posthog.ts restores it on init via the loaded callback:

import posthog from 'posthog-js';

// User accepts analytics cookies
function acceptAnalytics() {
  posthog.opt_in_capturing();
}

// User rejects analytics cookies
function rejectAnalytics() {
  posthog.opt_out_capturing();
}

// Check current status
const isOptedIn = posthog.has_opted_in_capturing();

Debugging

Enable Debug Mode

Debug mode is automatically enabled in development. For production debugging:

// In browser console
posthog.debug();

Common Issues

Issue Solution
No events appearing Check NEXT_PUBLIC_POSTHOG_KEY is set
No events despite key set Capturing is opt-out by default (opt_out_capturing_by_default: true) — accept analytics cookies first
No events on admin pages Expected: PostHog is deliberately not loaded on admin routes
Events delayed PostHog batches events, wait 1-2 minutes
Session recording not working Check disable_session_recording setting
User not identified Call identifyUser() after login

Test Event Capture

// In browser console
posthog.capture('test_event', { test: true });

Then check PostHog → Activity → Live Events.

Best Practices

  1. Use semantic event names: order_completed not click_buy_button
  2. Include relevant properties: Product ID, value, category
  3. Don't track PII: No passwords, full credit card numbers
  4. Use feature flags for rollouts: Gradual feature releases
  5. Set up alerts: For conversion rate drops