---
title: PostHog
description: PostHog is an open-source product analytics platform for tracking user behavior, session replays, feature flags, and A/B testing. It supports cookieless tracking, allowing analytics to continue even without cookie consent.
lastModified: 2025-09-19

icon: posthog
---
PostHog is an open-source product analytics platform that helps you understand user behavior, track events, and analyze product usage. Unlike traditional analytics tools, PostHog supports both cookieless and cookie-based tracking. This means you can sync c15t with PostHog and continue collecting analytics even when users haven't given consent—PostHog simply operates in cookieless mode until consent is granted.

## PostHog SDK Implementation

This is the recommended approach if you're using the Posthog JS SDK, this is commonly used in React projects.

### Adding the PostHog SDK to c15t

1. **Initialize Posthog** When you initialize posthog make sure to set cookieless\_mode to on\_reject.

   ```ts
   posthog.init("phc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", {
     api_host: "https://eu.i.posthog.com",
     defaults: "2025-05-24",
     cookieless_mode: 'on_reject'
   })

   posthog.has_opted_out_capturing() // Avoids accidental tracking without consent till c15t has loaded
   ```

2. **Adding the script to c15t**

   import \{ configureConsentManager } from 'c15t';
   import \{ posthog } from 'posthog-js';

   configureConsentManager(\{
   &#x20;// ...&#x20;
   &#x20;callbacks: \{
   &#x20;onConsentSet(\{ preferences }) \{
   &#x20;if (preferences.measurement) \{
   &#x20;posthog.opt\_in\_capturing();
   &#x20;} else \{
   &#x20;posthog.opt\_out\_capturing();
   &#x20;}
   &#x20;}
   &#x20;}
   });import \{ posthog } from 'posthog-js';
   import \{ ConsentManagerProvider } from '@c15t/react';

   export function App(\{ children }: \{ children: React.ReactNode }) \{
   &#x20;return (
   &#x20;\<ConsentManagerProvider
   &#x20;options=\{\{
   &#x20;callbacks: \{
   &#x20;onConsentSet(\{ preferences }) \{
   &#x20;if (preferences.measurement) \{
   &#x20;posthog.opt\_in\_capturing();
   &#x20;} else \{
   &#x20;posthog.opt\_out\_capturing();
   &#x20;}
   &#x20;}
   &#x20;}
   &#x20;}}
   &#x20;\>
   &#x20;\{children}
   &#x20;\</ConsentManagerProvider>
   &#x20;);
   }'use client';
   import \{ posthog } from 'posthog-js';
   import \{ ClientSideOptionsProvider } from '@c15t/nextjs/client';

   export function ConsentManagerClient(\{ children }: \{ children: React.ReactNode }) \{&#x20;
   &#x20;return (
   &#x20;\<ClientSideOptionsProvider
   &#x20;callbacks=\{\{
   &#x20;onConsentSet(\{ preferences }) \{
   &#x20;if (preferences.measurement) \{
   &#x20;posthog.opt\_in\_capturing();
   &#x20;} else \{
   &#x20;posthog.opt\_out\_capturing();
   &#x20;}
   &#x20;}
   &#x20;}}
   &#x20;\>
   &#x20;\{children}
   &#x20;\</ClientSideOptionsProvider>
   &#x20;);
   }import \{ posthog } from 'posthog-js';
   import \{ ConsentManagerProvider } from '@c15t/nextjs';

   export function App(\{ children }: \{ children: React.ReactNode }) \{
   return (
   \<ConsentManagerProvider
   options=\{\{
   // ... other options
   callbacks: \{
   &#x20;onConsentSet(\{ preferences }) \{
   &#x20;if (preferences.measurement) \{
   &#x20;posthog.opt\_in\_capturing();
   &#x20;} else \{
   &#x20;posthog.opt\_out\_capturing();
   &#x20;}
   &#x20;}
   }
   }}
   \>
   \{children}
   \</ConsentManagerProvider>
   );
   }

## PostHog Script Implementation

If you want to load posthog via a script tag it's recommended to use this approach.

By default c15t will always load the script regardless of consent. This is because the script has built-in functionality to opt into and out of tracking based on consent.

1. **Initialize Posthog** This script does not load the Posthog script, it only syncs the consent state with Posthog via the Posthog JS SDK.

   This is due to Posthog's use of cookieless tracking. However, you need to set cookieless\_mode to on\_reject when initializing Posthog.

   ```ts
   posthog.init("phc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", {
     api_host: "https://eu.i.posthog.com",
     defaults: "2025-05-24",
     // PostHog will not set any cookies until the user has given consent
     cookieless_mode: 'on_reject'
   })
   ```

2. **Adding the script to c15t**

   import \{ configureConsentManager } from 'c15t';
   import \{ posthog } from '@c15t/scripts/posthog';

   configureConsentManager(\{
   &#x20;// ...&#x20;
   &#x20;scripts: \[
   &#x20;posthog(\{&#x20;
   &#x20;id: 'phc\_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',&#x20;
   &#x20;apiHost: 'https\://eu.i.posthog.com',
   &#x20;defaults: '2025-05-24',&#x20;
   &#x20;options: \{ person\_profiles: 'identified\_only' }
   &#x20;}),
   &#x20;],
   });import \{ posthog } from '@c15t/scripts/posthog';
   import \{ ConsentManagerProvider } from '@c15t/react';

   export function App(\{ children }: \{ children: React.ReactNode }) \{
   &#x20;return (
   &#x20;\<ConsentManagerProvider
   &#x20;options=\{\{
   &#x20;scripts: \[
   &#x20;posthog(\{&#x20;
   &#x20;id: 'phc\_foobar',&#x20;
   &#x20;apiHost: 'https\://eu.i.posthog.com',
   &#x20;defaults: '2025-05-24',&#x20;
   &#x20;options: \{ person\_profiles: 'identified\_only' }
   &#x20;}),
   &#x20;],
   &#x20;}}
   &#x20;\>
   &#x20;\{children}
   &#x20;\</ConsentManagerProvider>
   &#x20;);
   }'use client';
   import \{ posthog } from '@c15t/scripts/posthog';
   import \{ ClientSideOptionsProvider } from '@c15t/nextjs/client';

   export function ConsentManagerClient(\{ children }: \{ children: React.ReactNode }) \{&#x20;
   &#x20;return (
   &#x20;\<ClientSideOptionsProvider
   &#x20;scripts=\{\[
   &#x20;posthog(\{&#x20;
   &#x20;id: 'phc\_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',&#x20;
   &#x20;apiHost: 'https\://eu.i.posthog.com',
   &#x20;defaults: '2025-05-24',&#x20;
   &#x20;options: \{ person\_profiles: 'identified\_only' }
   &#x20;}),
   &#x20;]}
   &#x20;\>
   &#x20;\{children}
   &#x20;\</ClientSideOptionsProvider>
   &#x20;);
   }import \{ posthog } from '@c15t/scripts/posthog';
   import \{ ConsentManagerProvider } from '@c15t/nextjs';

   export function App(\{ children }: \{ children: React.ReactNode }) \{
   &#x20;return (
   &#x20;\<ConsentManagerProvider
   &#x20;options=\{\{
   &#x20;scripts: \[
   &#x20;posthog(\{&#x20;
   &#x20;id: 'phc\_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',&#x20;
   &#x20;apiHost: 'https\://eu.i.posthog.com',
   &#x20;defaults: '2025-05-24',&#x20;
   &#x20;options: \{ person\_profiles: 'identified\_only' }
   &#x20;}),
   &#x20;],
   &#x20;}}
   &#x20;\>
   &#x20;\{children}
   &#x20;\</ConsentManagerProvider>
   &#x20;);
   }

## Types

### PosthogConsentOptions

| Property | Type                     | Description                                                                                                                              | Default                     |  Required  |
| :------- | :----------------------- | :--------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------- | :--------: |
| id       | string                   | Your posthog id, begins with 'phc\_'.                                                                                                    | -                           | ✅ Required |
| apiHost  | string                   | Your posthog api host.                                                                                                                   | 'https\://eu.i.posthog.com' | ✅ Required |
| defaults | string                   | The defaults for the posthog script.                                                                                                     | -                           | ✅ Required |
| options  | Record\<string, unknown> | Other optional options for the posthog script.                                                                                           | -                           | ✅ Required |
| script   | any                      | Override or extend the default script values.&#xA;&#xA;Default values:&#xA;- \`id\`: 'posthog-consent'&#xA;- \`category\`: 'measurement' | -                           |  Optional  |

### Script

| Property                   | Type                                              | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Default |  Required  |
| :------------------------- | :------------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------ | :--------: |
| id                         | string                                            | Unique identifier for the script                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | -       | ✅ Required |
| src                        | string \| undefined                               | URL of the script to load                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | -       |  Optional  |
| textContent                | string \| undefined                               | Inline JavaScript code to execute                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | -       |  Optional  |
| category                   | HasCondition\<AllConsentNames>                    | Consent category or condition required to load this script                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | -       | ✅ Required |
| callbackOnly               | boolean \| undefined                              | Whether this is a callback-only script that doesn't need to load an external resource.&#xA;When true, no script tag will be added to the DOM, only callbacks will be executed.&#xA;&#xA;This is useful for:&#xA;- Managing consent for libraries already loaded on the page&#xA;- Enabling/disabling tracking features based on consent changes&#xA;- Running custom code when consent status changes without loading external scripts&#xA;&#xA;Example use cases:&#xA;- Enabling/disabling Posthog tracking&#xA;- Configuring Google Analytics consent mode&#xA;- Managing cookie consent for embedded content | false   |  Optional  |
| persistAfterConsentRevoked | boolean \| undefined                              | Whether the script should persist after consent is revoked.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | false   |  Optional  |
| alwaysLoad                 | boolean \| undefined                              | Whether the script should always load regardless of consent state.&#xA;&#xA;This is useful for scripts like Google Tag Manager or PostHog that manage&#xA;their own consent state internally. The script will load immediately and&#xA;never be unloaded based on consent changes.&#xA;&#xA;Note: When using this option, you are responsible for ensuring the script&#xA;itself respects user consent preferences through its own consent management.                                                                                                                                                          | false   |  Optional  |
| fetchPriority              | "high" \| "low" \| "auto" \| undefined            | Priority hint for browser resource loading                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | -       |  Optional  |
| attributes                 | Record\<string, string> \| undefined              | Additional attributes to add to the script element                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | -       |  Optional  |
| async                      | boolean \| undefined                              | Whether to use async loading                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | -       |  Optional  |
| defer                      | boolean \| undefined                              | Whether to defer script loading                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | -       |  Optional  |
| nonce                      | string \| undefined                               | Content Security Policy nonce                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | -       |  Optional  |
| anonymizeId                | boolean \| undefined                              | Whether to use an anonymized ID for the script element, this helps ensure the script is not blocked by ad blockers                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | true    |  Optional  |
| target                     | "head" \| "body" \| undefined                     | Where to inject the script element in the DOM.&#xA;- \`'head'\`: Scripts are appended to \`\<head>\` (default)&#xA;- \`'body'\`: Scripts are appended to \`\<body>\`&#xA;&#xA;Use \`'body'\` for scripts that:&#xA;- Need to manipulate DOM elements that don't exist until body loads&#xA;- Should load after page content for performance reasons&#xA;- Are required by third-party services to be in the body&#xA;&#xA;Use \`'head'\` (default) for scripts that:&#xA;- Need to track early page events (analytics)&#xA;- Should be available before page render&#xA;- Most tracking/analytics scripts       | 'head'  |  Optional  |
| onBeforeLoad               | ((info: ScriptCallbackInfo) => void) \| undefined | Callback executed before the script is loaded                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | -       |  Optional  |
| onLoad                     | ((info: ScriptCallbackInfo) => void) \| undefined | Callback executed when the script loads successfully                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | -       |  Optional  |
| onDelete                   | ((info: ScriptCallbackInfo) => void) \| undefined | Callback executed when the script is being unloaded/removed                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | -       |  Optional  |
| onError                    | ((info: ScriptCallbackInfo) => void) \| undefined | Callback executed if the script fails to load                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | -       |  Optional  |
| onConsentChange            | ((info: ScriptCallbackInfo) => void) \| undefined | Callback executed whenever the consent store is changed.&#xA;This callback only applies to scripts already loaded.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | -       |  Optional  |
