11 KiB
PostHog Analytics Setup
This document describes how to set up PostHog Analytics for the Picture web application.
Overview
PostHog is a powerful product analytics platform that provides:
- 📊 Product Analytics: Track user behavior and product usage
- 🎯 Feature Flags: Roll out features gradually and A/B test
- 📹 Session Recordings: Watch how users interact with your app
- 🔥 Heatmaps: Visualize where users click and scroll
- 👥 User Profiles: Understand individual user journeys
Architecture
Web App (SvelteKit)
- Location:
apps/web/src/lib/analytics/posthog.ts - Framework: SvelteKit
- SDK: posthog-js
- Integration: Initialized in root layout with automatic user identification
Configuration
PostHog is configured using environment variables:
PUBLIC_POSTHOG_KEY=phc_your_posthog_project_api_key
PUBLIC_POSTHOG_HOST=https://us.i.posthog.com # or https://eu.i.posthog.com for EU
Environment Variables
Create or update apps/web/.env:
PUBLIC_POSTHOG_KEY=phc_xxxxxxxxxxxxxxxxx
PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
Note
: The
PUBLIC_prefix is required in SvelteKit to expose variables to the client.
Features
🔐 Privacy-First Configuration
- ✅ Identified Users Only:
person_profiles: 'identified_only'- only tracks logged-in users - ✅ localStorage Persistence: Uses localStorage instead of cookies
- ✅ No Autocapture: Manual event tracking for better control
- ✅ Session Recording Disabled: Can be enabled if needed
🚀 Automatic Features
- ✅ Pageview Tracking: Automatically tracks page navigation
- ✅ Page Leave Tracking: Tracks when users leave pages
- ✅ User Identification: Automatically identifies users on login/logout
- ✅ User Properties: Tracks email and account creation date
📊 Current Implementation
User Identification
Users are automatically identified on login with:
- User ID (from Supabase)
- Email address
- Account creation timestamp
// Automatically done on login
analytics.identify(user.id, {
email: user.email,
created_at: user.created_at
});
Session Management
- Login: User is identified in PostHog
- Logout: PostHog session is reset
- Auth State Changes: PostHog identity is updated automatically
Setup Steps
1. Create PostHog Account
You have two options:
Option A: PostHog Cloud (Recommended)
- Sign up at posthog.com
- Create a new project
- Select your region (US or EU)
- Copy your Project API Key (starts with
phc_)
Option B: Self-Hosted PostHog
- Follow the PostHog deployment guide
- Deploy to your preferred platform
- Create a project
- Note your instance URL and API key
2. Configure Environment Variables
Development
-
Copy
.env.exampleto.envinapps/web:cd apps/web cp .env.example .env -
Add your PostHog credentials:
PUBLIC_POSTHOG_KEY=phc_your_actual_api_key PUBLIC_POSTHOG_HOST=https://us.i.posthog.com # or eu.i.posthog.com
Production
Add environment variables to your deployment platform:
Vercel:
vercel env add PUBLIC_POSTHOG_KEY
vercel env add PUBLIC_POSTHOG_HOST
Netlify:
- Go to Site settings → Environment variables
- Add
PUBLIC_POSTHOG_KEYandPUBLIC_POSTHOG_HOST
Other platforms:
- Follow your platform's documentation for environment variables
- Ensure variables are prefixed with
PUBLIC_
3. Verify Integration
-
Start the development server:
cd apps/web pnpm dev -
Open browser DevTools → Console
-
Look for "PostHog loaded" message (in dev mode)
-
Navigate between pages
-
Log in with a test account
-
Check PostHog dashboard for events
Usage
Tracking Custom Events
The analytics helper provides easy-to-use methods:
import { analytics } from '$lib/analytics/posthog';
// Track a custom event
analytics.track('button_clicked', {
button_name: 'sign_up',
page: '/pricing'
});
// Track image generation
analytics.track('image_generated', {
model: 'flux-dev',
prompt_length: 150,
aspect_ratio: '16:9'
});
// Track feature usage
analytics.track('feature_used', {
feature: 'batch_generation',
count: 5
});
User Properties
Set additional user properties:
import { analytics } from '$lib/analytics/posthog';
analytics.setUserProperties({
plan: 'pro',
images_generated: 42,
favorite_model: 'flux-dev'
});
Feature Flags
Use feature flags for gradual rollouts and A/B testing:
import { analytics } from '$lib/analytics/posthog';
// Check if a feature is enabled
const showNewUI = analytics.isFeatureEnabled('new_ui_redesign');
// Get feature flag value (for multivariate flags)
const buttonColor = analytics.getFeatureFlag('button_color_test');
Page View Tracking
Page views are tracked automatically. For manual tracking:
import { analytics } from '$lib/analytics/posthog';
// Track a specific page view
analytics.pageView('/custom-page');
Example Use Cases
Track Image Generation
// In your image generation component
import { analytics } from '$lib/analytics/posthog';
async function generateImage(prompt: string, settings: Settings) {
// Track the generation attempt
analytics.track('image_generation_started', {
model: settings.model,
prompt_length: prompt.length,
aspect_ratio: settings.aspectRatio,
num_images: settings.numImages
});
try {
const result = await generateImageAPI(prompt, settings);
// Track success
analytics.track('image_generation_completed', {
model: settings.model,
generation_time_ms: result.duration
});
return result;
} catch (error) {
// Track errors
analytics.track('image_generation_failed', {
model: settings.model,
error: error.message
});
throw error;
}
}
Track User Engagement
// Track when users interact with images
analytics.track('image_liked', {
image_id: image.id,
model: image.model
});
analytics.track('image_shared', {
image_id: image.id,
platform: 'twitter'
});
analytics.track('image_downloaded', {
image_id: image.id,
format: 'png'
});
Track Feature Discovery
// Track when users discover features
analytics.track('feature_discovered', {
feature: 'batch_generation',
source: 'tooltip'
});
analytics.track('tutorial_completed', {
tutorial: 'first_generation'
});
PostHog Dashboard
Key Metrics to Track
-
User Engagement
- Daily/Weekly/Monthly Active Users
- Session duration
- Pages per session
-
Feature Usage
- Image generation count
- Most used models
- Popular aspect ratios
- Batch generation usage
-
User Journey
- Signup → First generation time
- Feature adoption rate
- Retention cohorts
-
Errors & Issues
- Generation failures
- Error rates by model
- API timeout frequency
Creating Insights
-
Funnel Analysis
Sign Up → First Generation → Image Download → Share -
Retention
Track users who return after first generation -
Trends
Image generations over time Model popularity trends
Feature Flags Setup
Create a Feature Flag
- Go to PostHog → Feature Flags
- Click "New feature flag"
- Set flag key (e.g.,
new_ui_redesign) - Configure rollout percentage
- Save and deploy
Use in Code
<script lang="ts">
import { analytics } from '$lib/analytics/posthog';
import { onMount } from 'svelte';
let showNewUI = false;
onMount(() => {
showNewUI = analytics.isFeatureEnabled('new_ui_redesign');
});
</script>
{#if showNewUI}
<NewUIComponent />
{:else}
<OldUIComponent />
{/if}
Session Recordings (Optional)
Session recordings are disabled by default for privacy. To enable:
-
Update
apps/web/src/lib/analytics/posthog.ts:disable_session_recording: false, // Enable recordings -
Configure in PostHog dashboard:
- Set recording sample rate
- Configure privacy settings
- Set up retention period
-
Add privacy notice to your app
Privacy & Compliance
GDPR Compliance
- ✅ Only tracks identified (logged-in) users
- ✅ Users can opt-out via PostHog settings
- ✅ Data retention policies can be configured
- ✅ Personal data can be deleted on request
User Opt-Out
To allow users to opt-out:
import posthog from '$lib/analytics/posthog';
// Opt user out
posthog.opt_out_capturing();
// Opt user back in
posthog.opt_in_capturing();
Data Deletion
To delete user data (on account deletion):
import { analytics } from '$lib/analytics/posthog';
// Reset all user data
analytics.reset();
Troubleshooting
PostHog Not Loading
- ✅ Verify
PUBLIC_POSTHOG_KEYis set correctly - ✅ Check
PUBLIC_POSTHOG_HOSTmatches your region - ✅ Ensure environment variables have
PUBLIC_prefix - ✅ Restart dev server after adding env vars
No Events in Dashboard
- ✅ Verify API key matches PostHog project
- ✅ Check browser console for errors
- ✅ Ensure user is logged in (only tracks identified users)
- ✅ Check ad blocker isn't blocking requests
Feature Flags Not Working
- ✅ Wait a few minutes after creating flag
- ✅ Verify flag key matches code
- ✅ Check user is identified
- ✅ Ensure flag is enabled in PostHog
Development vs Production
- Development: All events are tracked, console logging enabled
- Production: Production mode, no console logs
- Testing: Use a separate PostHog project for testing
Advanced Configuration
Custom Initialization
To customize PostHog initialization, edit apps/web/src/lib/analytics/posthog.ts:
posthog.init(PUBLIC_POSTHOG_KEY, {
api_host: PUBLIC_POSTHOG_HOST,
// Capture settings
capture_pageview: true,
capture_pageleave: true,
// Session settings
session_recording: {
recordCrossOriginIframes: false,
maskAllInputs: true,
maskTextSelector: '.sensitive'
},
// Privacy settings
respect_dnt: true,
opt_out_capturing_by_default: false,
// Performance
persistence: 'localStorage',
autocapture: false,
// Advanced features
enable_recording_console_log: true,
disable_compression: false
});
Proxy Setup (Avoid Ad Blockers)
For production, proxy PostHog through your domain:
- Set up a reverse proxy (e.g., Cloudflare Worker)
- Update
PUBLIC_POSTHOG_HOSTto your proxy URL - Configure CORS headers
Example Cloudflare Worker:
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
const url = new URL(request.url)
url.hostname = 'us.i.posthog.com'
return fetch(url, {
method: request.method,
headers: request.headers,
body: request.body
})
}
Resources
- PostHog Documentation
- PostHog JavaScript SDK
- Feature Flags Guide
- Session Recordings
- Privacy Controls
Support
For issues specific to:
- PostHog Platform: PostHog Support
- Integration Code: Create an issue in this repository
- Privacy/Compliance: Consult with your legal team