What is PostHog?
PostHog is an open-source product analytics platform that tells you what real users are doing on your website or app. Unlike Google Analytics — which focuses on traffic numbers — PostHog focuses on behaviour: which buttons people click, where they abandon your onboarding flow, what happens in the 30 seconds before someone signs up or leaves forever.
It's built for product teams and indie developers who want Google Analytics, Hotjar, and Optimizely in one tool, on a free plan, without sending data to a dozen third parties.
The free tier covers 1 million events per month — enough for most early-stage products. When you outgrow it, pricing scales gradually.
What PostHog tracks
| Feature | What it does |
|---|---|
| Web analytics | Pageviews, sessions, bounce rate, top pages |
| Product analytics | Custom events, funnels, retention, trends |
| Session replay | Video recordings of actual user sessions |
| Feature flags | Roll out features to % of users safely |
| A/B testing | Test two versions of any UI element |
| Surveys | In-app feedback prompts |
You don't need all of these on day one. Most people start with analytics + session replay, then add the rest as they grow.
Step-by-step setup for a Next.js site
This is exactly how SimpleAI wired up PostHog — you can follow the same steps for any Next.js project.
1. Create a PostHog account
- Go to posthog.com and sign up free
- During onboarding, choose your data region — pick EU if your users are in Europe (GDPR compliance), US otherwise
- Skip the AI wizard — you'll configure it manually
2. Get your Project API key
- In the PostHog sidebar, click Settings (gear icon next to your project name)
- Find Project API Key — it starts with
phc_ - Copy it — this is your public token (safe to expose in frontend code)
3. Install the SDK
npm install posthog-js
4. Create a PostHog provider component
Create src/components/PostHogProvider.tsx:
"use client";
import posthog from "posthog-js";
import { PostHogProvider as PHProvider } from "posthog-js/react";
import { useEffect } from "react";
export function PostHogProvider({ children }: { children: React.ReactNode }) {
useEffect(() => {
const key = process.env.NEXT_PUBLIC_POSTHOG_KEY;
if (!key) return;
posthog.init(key, {
api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST ?? "https://app.posthog.com",
capture_pageview: true,
capture_pageleave: true,
person_profiles: "identified_only",
session_recording: {
maskAllInputs: true, // hides passwords/emails in recordings
},
});
}, []);
if (!process.env.NEXT_PUBLIC_POSTHOG_KEY) return <>{children}</>;
return <PHProvider client={posthog}>{children}</PHProvider>;
}
5. Wrap your app
In src/app/layout.tsx, wrap everything with PostHogProvider:
import { PostHogProvider } from "@/components/PostHogProvider";
export default function RootLayout({ children }) {
return (
<html>
<body>
<PostHogProvider>
{children}
</PostHogProvider>
</body>
</html>
);
}
6. Add your environment variables
In .env.local:
NEXT_PUBLIC_POSTHOG_KEY=phc_your_key_here
NEXT_PUBLIC_POSTHOG_HOST=https://eu.posthog.com
If deploying to Vercel: go to Settings → Environment Variables and add both. The NEXT_PUBLIC_ prefix is intentional — PostHog tokens are designed to be public (they can only write events, not read your data).
7. Track custom events
Anywhere in your client components, call posthog.capture():
import posthog from "posthog-js";
// Track a button click
posthog.capture("quiz_started");
// Track with properties
posthog.capture("quiz_completed", {
persona: "the-analyst",
steps_taken: 10,
});
8. Identify signed-in users
When a user signs in, link their anonymous session to their identity:
posthog.identify(user.uid, {
email: user.email,
name: user.displayName,
});
This connects all their anonymous activity (before sign-in) to their profile. When they sign out:
posthog.reset(); // clears the identity, next session is anonymous again
Events worth tracking on any website
These custom events give you the most insight for the least effort:
// Auth
posthog.capture("user_signed_up", { method: "google" });
posthog.capture("user_signed_in", { method: "email" });
posthog.capture("user_signed_out");
// Onboarding / key flows
posthog.capture("onboarding_started");
posthog.capture("onboarding_step_completed", { step: 2, name: "profile_setup" });
posthog.capture("onboarding_completed");
// Core product actions
posthog.capture("feature_used", { feature: "quiz" });
posthog.capture("item_saved", { item_type: "tool" });
posthog.capture("share_clicked", { content: "quiz_result" });
The pattern is: noun + past tense verb (quiz_completed, not completeQuiz or quiz). Keep names consistent and you'll thank yourself when building funnels later.
Reading your data in PostHog
Activity feed
Left sidebar → Activity — raw stream of every event as it comes in. Good for verifying your setup is working immediately after deploying.
Web analytics
Left sidebar → Web Analytics — traffic overview. Visitors, pageviews, top pages, session duration. Needs capture_pageview: true in your init config.
Funnels
Product analytics → New insight → Funnel — define a sequence of events and see what % of users complete each step. Essential for understanding where people drop off in signups, onboarding, or checkout.
Session replay
Session replay in the sidebar — watch actual recordings. Filter by event (e.g. "show me sessions where the user hit an error") to find exactly the recordings worth watching. Inputs are masked by default if you set maskAllInputs: true.
EU region vs US region
If your users are in Europe, choose the EU region when creating your account. This keeps all data on EU servers (Frankfurt), which simplifies GDPR compliance. Your api_host should be https://eu.posthog.com instead of the default https://app.posthog.com.
You set the region once at account creation — it can't be changed later without creating a new project.
PostHog vs alternatives
| PostHog | Google Analytics 4 | Mixpanel | |
|---|---|---|---|
| Free tier | 1M events/mo | Unlimited (sampled) | 20M events/mo |
| Session replay | Yes | No | No |
| Feature flags | Yes | No | No |
| Open-source | Yes | No | No |
| Self-hostable | Yes | No | No |
| Setup complexity | Medium | Easy | Medium |
| Best for | Product teams, builders | Marketing / SEO | Growth teams |
Pick PostHog if you're building a product and want to understand user behaviour in detail, especially with session replay. Pick Google Analytics if you primarily care about SEO traffic and marketing attribution — it integrates more naturally with Google Ads. Pick Mixpanel if you're at scale and need enterprise-grade cohort analysis.