# Using the PostHog Analytics Provider in Next.js Supabase Turbo

> Add PostHog to your MakerKit application for product analytics, session replay, and feature flags with client-side and server-side support.

*Canonical: https://makerkit.dev/docs/next-supabase-turbo/analytics/posthog-analytics-provider*

---

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. 

Posthog 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](https://posthog.com)
- Note your Project API Key (starts with `phc_`)
- Choose your region: `eu.posthog.com` or `us.posthog.com`

Find your API key in PostHog: **Project Settings > Project API Key**.

## Installation

Install the PostHog plugin using the MakerKit CLI:

```bash
npx @makerkit/cli@latest plugins add posthog
```

Our codemod will wire up the plugin in your project, so you don't have to do anything manually. Please review the changes with `git diff`.

Add environment variables:

```bash {% title=".env.local" %}
NEXT_PUBLIC_POSTHOG_KEY=phc_your_key_here
NEXT_PUBLIC_POSTHOG_HOST=https://eu.posthog.com
```

Use `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:

Use server-side tracking in your code:

```typescript
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

```bash {% title=".env.local" %}
NEXT_PUBLIC_POSTHOG_KEY=phc_your_key_here
NEXT_PUBLIC_POSTHOG_HOST=https://eu.posthog.com
NEXT_PUBLIC_POSTHOG_INGESTION_URL=http://localhost:3000/ingest
```

In production, replace `localhost:3000` with your domain.

### Step 2: Configure Next.js Rewrites

Add rewrites to your Next.js configuration:

```javascript {% title="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 Ingestion Endpoint from Middleware

Ensure the ingestion endpoint is excluded from the middleware matcher:

```typescript {% title="apps/web/proxy.ts" %}
export const config = {
  matcher: [
    '/((?!_next/static|_next/image|images|locales|assets|ingest/*|api/*).*)',
  ],
};
```

## 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:

1. Open your application
2. Navigate between pages
3. Open PostHog > Activity > Live Events
4. 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:

```typescript {% title="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](/docs/next-supabase-turbo/monitoring/posthog).

## 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: true` is 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

{% faq
   title="Frequently Asked Questions"
   items=[
     {"question": "Should I use the EU or US region?", "answer": "Use the EU region (eu.posthog.com) if you have European users and want GDPR-compliant data residency. The US region may have slightly lower latency for US-based users."},
     {"question": "Can I self-host PostHog?", "answer": "Yes. PostHog can be self-hosted using Docker. Update NEXT_PUBLIC_POSTHOG_HOST to your self-hosted instance URL."},
     {"question": "How do I enable session replay?", "answer": "Session replay is enabled by default in PostHog. Configure recording settings in PostHog > Project Settings > Session Replay."},
     {"question": "Do ingestion rewrites work on Vercel?", "answer": "Yes. The rewrites in next.config.mjs work on Vercel and other Next.js hosting platforms."},
     {"question": "Is PostHog GDPR compliant?", "answer": "PostHog can be GDPR compliant. Use the EU region for data residency, enable cookie-less tracking, and integrate with a consent management solution."}
   ]
/%}

## Next Steps

- [Learn about Analytics and Events](analytics-and-events) for custom event tracking
- [Set up PostHog for monitoring](/docs/next-supabase-turbo/monitoring/posthog)
- [Try Umami](umami-analytics-provider) for simpler, privacy-focused analytics
