---
title: PostHog integration
description: Send survey activity and selected ratings to your existing PostHog client.
package: "@userreason/js"
version: "0.5.4"
since: "0.4.0"
url: https://docs.userreason.com/sdk/posthog/
updated: 2026-10-17
---

# PostHog integration

Connect UserReason to the `posthog-js` instance already initialized by your application. Survey activity appears as custom events alongside product activity in PostHog. The connector is a separate import; it adds no PostHog dependency to the main UserReason SDK.

## Connect

```ts
import userreason from '@userreason/js';
import posthog from 'posthog-js';
import { connectPostHog } from '@userreason/js/posthog';

// The application has already initialized this PostHog instance.
const disconnect = connectPostHog(userreason, posthog);

userreason.init({
  siteId: '22222222-2222-4222-8222-222222222222',
});

// During application teardown:
// disconnect();
// userreason.destroy();
```

Connect before `init()` to include surveys displayed at startup. The default singleton and instances created with `new UserReason()` both work. The connector does not initialize PostHog, change its configuration, or request another key.

## Export selected ratings

Answers are excluded by default. Select the numeric rating questions you want to analyse:

```ts
import userreason from '@userreason/js';
import posthog from 'posthog-js';
import { connectPostHog } from '@userreason/js/posthog';

const disconnect = connectPostHog(userreason, posthog, {
  ratings: {
    portfolio_ease: {
      surveyId: '44444444-4444-4444-8444-444444444444',
      questionId: 'ease',
    },
  },
});

userreason.init({ siteId: '22222222-2222-4222-8222-222222222222' });
```

Use the survey ID returned by the dashboard or CLI, and the question's stable ID from its definition. An underlying survey ID is also accepted, as with [`show()`](https://docs.userreason.com/sdk/show/index.md). Matching does not depend on question order or wording.

This mapping adds `userreason_rating_portfolio_ease: 2` when that survey is completed with a rating of 2. Unanswered questions and non-rating answers are omitted; zero is preserved when it is an actual rating. Aliases must start with a lowercase letter and contain only lowercase letters, digits and underscores, up to 64 characters. Up to 64 ratings can be selected. Options are copied when connecting; call `connectPostHog()` again to apply a changed mapping.

Free text, typed fields, option selections, matrices, answer timing and other response content are not forwarded. The numeric scale is the survey's scale; the connector does not normalize it. Filter by `userreason_survey_version_id` when comparing results across versions with different scales or meaning.

## Events and properties

| Event | When it is sent |
| - | - |
| `userreason_shown` | The survey becomes visible. |
| `userreason_submitted` | UserReason accepts the completed response. |
| `userreason_dismissed` | The visitor closes the survey before completing it. |

Closing the thank-you screen does not produce `userreason_dismissed`. Saving a partial response does not produce `userreason_submitted`. SDK errors are not forwarded.

All events use schema version 1 and include available context:

| Property | Meaning |
| - | - |
| `userreason_schema_version` | Connector event schema version, currently `1`. |
| `userreason_workspace_id`, `userreason_site_id` | UserReason scope. |
| `userreason_campaign_id` | Public survey ID returned by the dashboard or CLI. |
| `userreason_survey_id` | Underlying survey ID. |
| `userreason_survey_version_id` | Version of the survey shown to this visitor. |
| `userreason_impression_id` | This particular admitted display. |
| `userreason_language` | Interface language used for the survey. |

Submission events also include `userreason_response_id`, `userreason_submitted_at` (an ISO timestamp), and any selected `userreason_rating_<alias>` properties. The connector explicitly selects these properties; it does not copy the entire response. These are custom analytics events, not entries in PostHog's Surveys interface.

## Identity and consent

The connector calls the supplied client's `capture()` method, using its current identity and capture settings. Identify accounts explicitly in both products after login, and reset both at logout. The connector never copies PostHog's anonymous ID into UserReason or identifies a person itself. See [UserReason identity](https://docs.userreason.com/sdk/identity/index.md) and [PostHog JavaScript usage](https://posthog.com/docs/libraries/js/usage).

Your application manages consent and UserReason storage. The connector does not opt users in, override PostHog capture settings, or keep a queue for replay after consent. When appropriate, connect after consent and call `disconnect()` when consent is withdrawn. Previously captured events are not deleted by disconnecting.

## Lifecycle and delivery

Call the returned `disconnect()` function to stop forwarding. It is safe to call more than once. Reconnecting the same UserReason/PostHog pair replaces its previous subscription; an older disconnect function cannot remove the new connection. Different clients and UserReason instances remain independent.

`reset()` and account changes preserve the subscription. `destroy()` removes all SDK listeners: disconnect during teardown, and connect again before reinitialization. PostHog's lifecycle remains owned by your application.

Delivery to PostHog is best effort. A successful UserReason submission confirms storage in UserReason, not delivery to PostHog. Capture failures cannot fail the visitor's submission. The connector has no network client, retry queue or persistent storage of its own. It suppresses duplicate notifications using the most recent 256 event/response identifiers per connection; this is not a guarantee of exactly-once delivery.

## Analyse low ratings

1. Complete a survey with the selected rating question.
2. Find `userreason_submitted` in PostHog's activity view and inspect `userreason_rating_portfolio_ease`.
3. Create a funnel starting with that event, filtered to the scores of interest, followed by a product event such as returning to the portfolio.
4. Compare against another score group using the same time window and survey version.

Use the application's existing PostHog identity consistently so survey activity and subsequent product activity belong to the same person. See [PostHog custom event capture](https://posthog.com/docs/product-analytics/capture-events).
