> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sazabi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# PostHog SDK

> Configure a reverse proxy to send posthog-js browser capture traffic to a Sazabi endpoint instead of PostHog.

[All PostHog integration capabilities](https://docs.sazabi.com/catalogs/integrations/posthog)

## About

Forward browser `posthog-js` capture traffic — analytics events, identify calls, and session replay snapshots — into Sazabi by routing SDK traffic through a reverse proxy you control. The proxy sends browser capture traffic (the `/e/`, `/i/`, and `/s/` paths) to Sazabi **instead of** PostHog, and still sends PostHog's config, feature-flag, and asset traffic to PostHog. Sazabi does not forward capture traffic on to PostHog.

> [!WARNING]
>
> With this setup, PostHog stops receiving analytics events, identify calls, and session replays from this app. To keep PostHog receiving events and also send them to Sazabi, use the [PostHog](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/posthog.md) source instead. PostHog's Data Pipeline (a paid PostHog feature) forwards events, not session replays, to Sazabi.

> [!WARNING]
>
> This source captures only what `posthog-js` sends from the browser. It does not cover server-side PostHog events — use the PostHog CDP webhook source for those.

Session replay is controlled by your PostHog project settings, not a `posthog.init` option.

## Prerequisites

* A `posthog-js` browser application.
* A reverse proxy you control (for example a Next.js rewrite, Nginx, or Cloudflare Worker) that can split PostHog SDK routes by path.
* Your Sazabi intake URL (shown above).

## Set up in the dashboard

**Step 1**

### Plan the reverse proxy

Configure `posthog-js` to use a reverse proxy path as `api_host`. Send capture paths (`/e/`, `/i/`, `/s/`) to Sazabi, and send PostHog config, flags, and assets to PostHog.

Use your Sazabi intake URL (shown above) as the upstream destination for capture-path proxy rules.

**Step 2**

### Initialize posthog-js

Point `posthog-js` at your reverse proxy path:

**JavaScript**

```javascript theme={"system"}
import posthog from "posthog-js";

posthog.init("<your phc_* project token>", {
  api_host: "/ingest",
  ui_host: "https://us.posthog.com",
});
```

**Next.js**

```typescript theme={"system"}
"use client";

import posthog from "posthog-js";
import { PostHogProvider } from "posthog-js/react";

if (typeof window !== "undefined") {
  posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
    api_host: "/ingest",
    ui_host: "https://us.posthog.com",
  });
}

export function Providers({ children }: { children: React.ReactNode }) {
  return <PostHogProvider client={posthog}>{children}</PostHogProvider>;
}
```

**Step 3**

### Configure rewrites

Route capture paths to Sazabi and all other PostHog paths back to PostHog. Capture traffic that reaches Sazabi does not reach PostHog. For Next.js:

> [!WARNING]
>
> On Next.js, set `skipTrailingSlashRedirect: true`. Otherwise Next.js sends a
> 308 redirect on the trailing-slash capture paths (`/e/`, `/i/v0/e/`, `/s/`),
> which stops them from matching the Sazabi rule.

```typescript theme={"system"}
// next.config.ts
import type { NextConfig } from "next";

const config: NextConfig = {
  // posthog-js posts to trailing-slash capture paths (/e/, /i/v0/e/, /s/). Without
  // this, Next.js 308-redirects them to the slash-less path, which no longer matches
  // the capture rule below and falls through to PostHog.
  skipTrailingSlashRedirect: true,
  async rewrites() {
    return [
      {
        source: "/ingest/:path((?:e|i|s)/.*)",
        destination: "https://your-intake-host/:path*",
      },
      {
        source: "/ingest/:path*",
        destination: "https://us.i.posthog.com/:path*",
      },
    ];
  },
};

export default config;
```

Replace `your-intake-host` with the hostname portion of your intake URL (shown above, without `https://`).

**Step 4**

### Hand off the change

Commit these changes on a new branch, push it, and open a pull request. Keep the intake URL and any keys in environment variables or a secret store, and commit only configuration that references them.

## Set up with the CLI

You can also register the PostHog SDK log source with the [Sazabi CLI](https://docs.sazabi.com/reference/cli.md) (installed and authenticated — see [CLI reference](https://docs.sazabi.com/reference/cli/log-sources.md)).

Registering the source mints the same intake URL the dashboard shows above (the public key is embedded in its hostname):

```bash theme={"system"}
sazabi log-sources create posthog_sdk --mode manual
```

The command prints the intake URL for the new source — copy the whole URL and point your sender at it using the configuration shown above. Run `sazabi log-sources get <log-source-id>` at any time to reprint the endpoint, or `sazabi log-sources list` to see every log source in the project.

## Verify

Load your application and generate a browser event (for example a page view or a button click). Open the [Intake page](https://docs.sazabi.com/guides/instrument/intake.md) in the Sazabi dashboard and confirm records from the **PostHog SDK** source appear. Records typically arrive within a minute or two.

## Troubleshooting

**No records appear** — Confirm the rewrite routes for `/e/`, `/i/`, and `/s/` paths resolve to your Sazabi intake hostname. Check the browser network tab for the capture request and verify it returns a 2xx from Sazabi.

**Session replay snapshots not forwarding** — Session replay uses the `/s/` path. Confirm your proxy rule covers `/s/.*` and is not blocked by a more general PostHog passthrough rule that precedes the Sazabi capture rule.

**Next.js 308 redirect loop** — Without `skipTrailingSlashRedirect: true`, Next.js redirects trailing-slash paths before the rewrite runs. The redirect destination (`/e` without the slash) no longer matches the capture rule and falls through to PostHog instead of Sazabi.

**Events or session replays missing in PostHog** — This is expected with this setup. Capture paths (`/e/`, `/i/`, `/s/`) go to Sazabi instead of PostHog. To keep PostHog receiving events, use the [PostHog](https://docs.sazabi.com/catalogs/log-sources/send-to-an-endpoint/posthog.md) source instead.

## Further reading

> [card] [Intake](https://docs.sazabi.com/guides/instrument/intake.md)
>
> See per-source ingestion volume and health in the Intake page.

> [card] [Log sources](https://docs.sazabi.com/catalogs/log-sources.md)
>
> Browse the full log source catalog.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.