PostHog Analytics Setup in MakerKit
Add PostHog to your MakerKit application for product analytics, session replay, and feature flags with client-side and server-side support.
PostHog provides product analytics, session replay, feature flags, and A/B testing in one platform. Unlike marketing-focused tools, PostHog helps you understand how users interact with your product. It supports both client-side and server-side tracking, and can be self-hosted for full data control.
Prerequisites
Before starting:
- Create a PostHog account at posthog.com
- Note your Project API Key (starts with
phc_) - Choose your region:
eu.posthog.comorus.posthog.com
Find your API key in PostHog: Project Settings > Project API Key.
Installation
Install the PostHog plugin using the MakerKit CLI:
npx @makerkit/cli@latest plugins installSelect PostHog from the list. This creates the plugin at packages/plugins/posthog.
Add the plugin as a dependency to the analytics package:
pnpm add "@kit/posthog@workspace:*" --filter "@kit/analytics" -DClient-Side Configuration
Register the provider for client-side analytics:
packages/analytics/src/index.ts
import { createPostHogAnalyticsService } from '@kit/posthog/client';import { createAnalyticsManager } from './analytics-manager';import type { AnalyticsManager } from './types';export const analytics: AnalyticsManager = createAnalyticsManager({ providers: { posthog: createPostHogAnalyticsService, },});Add environment variables:
.env.local
NEXT_PUBLIC_POSTHOG_KEY=phc_your_key_hereNEXT_PUBLIC_POSTHOG_HOST=https://eu.posthog.comUse https://us.posthog.com if your project is in the US region.
Server-Side Configuration
PostHog supports server-side analytics for tracking events in API routes and Server Actions:
packages/analytics/src/server.ts
import 'server-only';import { createPostHogAnalyticsService } from '@kit/posthog/server';import { createAnalyticsManager } from './analytics-manager';import type { AnalyticsManager } from './types';export const analytics: AnalyticsManager = createAnalyticsManager({ providers: { posthog: createPostHogAnalyticsService, },});Use server-side tracking in your code:
import { analytics } from '@kit/analytics/server';export async function createProject(data: ProjectData) { const project = await db.projects.create(data); await analytics.trackEvent('project.created', { projectId: project.id, userId: data.userId, }); return project;}Bypassing Ad Blockers with Ingestion Rewrites
Ad blockers frequently block PostHog. Use Next.js rewrites to proxy requests through your domain:
Step 1: Add the Ingestion URL
.env.local
NEXT_PUBLIC_POSTHOG_KEY=phc_your_key_hereNEXT_PUBLIC_POSTHOG_HOST=https://eu.posthog.comNEXT_PUBLIC_POSTHOG_INGESTION_URL=http://localhost:3000/ingestIn production, replace localhost:3000 with your domain.
Step 2: Configure Next.js Rewrites
Add rewrites to your Next.js configuration:
apps/web/next.config.mjs
/** @type {import('next').NextConfig} */const config = { // Required for PostHog trailing slash API requests skipTrailingSlashRedirect: true, async rewrites() { // Change 'eu' to 'us' if using the US region return [ { source: '/ingest/static/:path*', destination: 'https://eu-assets.i.posthog.com/static/:path*', }, { source: '/ingest/:path*', destination: 'https://eu.i.posthog.com/:path*', }, ]; },};export default config;Step 3: Exclude from CSRF Protection
Exclude the ingestion endpoint from CSRF middleware:
apps/web/proxy.ts
export const config = { matcher: [ '/((?!_next/static|_next/image|images|locales|assets|ingest/*|api/*).*)', ],};Note: For versions prior to Next.js 16, use apps/web/middleware.ts instead.
Environment Variables
| Variable | Required | Description |
|---|---|---|
NEXT_PUBLIC_POSTHOG_KEY | Yes | Your PostHog Project API Key |
NEXT_PUBLIC_POSTHOG_HOST | Yes | PostHog host (https://eu.posthog.com or https://us.posthog.com) |
NEXT_PUBLIC_POSTHOG_INGESTION_URL | No | Proxy URL to bypass ad blockers (e.g., https://yourdomain.com/ingest) |
Verification
After configuration:
- Open your application
- Navigate between pages
- Open PostHog > Activity > Live Events
- Confirm page views and events appear
If using ingestion rewrites, check the Network tab for requests to /ingest instead of posthog.com.
Using with Other Providers
PostHog works alongside other analytics providers:
packages/analytics/src/index.ts
import { createPostHogAnalyticsService } from '@kit/posthog/client';import { createGoogleAnalyticsService } from '@kit/google-analytics';import { createAnalyticsManager } from './analytics-manager';export const analytics = createAnalyticsManager({ providers: { posthog: createPostHogAnalyticsService, 'google-analytics': createGoogleAnalyticsService, },});PostHog Features Beyond Analytics
PostHog offers additional features beyond event tracking:
- Session Replay: Watch user sessions to debug issues
- Feature Flags: Control feature rollouts
- A/B Testing: Run experiments on UI variants
- Surveys: Collect user feedback
These features are available in the PostHog dashboard once you are capturing events.
For monitoring features (error tracking), see the PostHog Monitoring guide.
Troubleshooting
Events not appearing
- Verify your API key starts with
phc_ - Confirm the host matches your project region (EU vs US)
- Check for ad blockers if not using ingestion rewrites
CORS errors with ingestion rewrites
- Ensure
skipTrailingSlashRedirect: trueis set in next.config.mjs - Verify the rewrite destination matches your region
Server-side events not appearing
- Ensure you import from
@kit/analytics/server, not@kit/analytics - Server-side tracking requires the same environment variables
Frequently Asked Questions
Should I use the EU or US region?
Can I self-host PostHog?
How do I enable session replay?
Do ingestion rewrites work on Vercel?
Is PostHog GDPR compliant?
Next Steps
- Learn about Analytics and Events for custom event tracking
- Set up PostHog for monitoring
- Try Umami for simpler, privacy-focused analytics