Skip to content

feat(replay): support session replay v2 trigger groups - #850

Open
marc-merino wants to merge 1 commit into
PostHog:mainfrom
marc-merino:knit/session-replay-v2-trigger-groups-on-mobile
Open

marc-merino wants to merge 1 commit into
PostHog:mainfrom
marc-merino:knit/session-replay-v2-trigger-groups-on-mobile

Conversation

@marc-merino

@marc-merino marc-merino commented Oct 7, 2026 •

Copy link
Copy Markdown

Knit Bundle

View bundle

This PR is part of Knit bundle session-replay-v2-trigger-groups-on-mobile.

See the other review objects in this bundle:

Bundle id: session-replay-v2-trigger-groups-on-mobile
Bundle title: Session replay v2 trigger groups on mobile

One of four PRs adding session replay v2 trigger groups to the mobile SDKs (Android, iOS, React Native, Flutter). You can see the unified description of the whole change here: Svartal bundle. The four PRs are linked above.

💡 Motivation and Context

Closes #712.

The server and posthog-js already support session replay v2 trigger groups (sessionRecording.version: 2 with a triggerGroups array). This SDK ignored them, so a project configured with trigger groups recorded on Android without the per-group conditions or sampling.

This PR evaluates the groups the same way posthog-js does (V2TriggerGroupStrategy):

  • Each group has event, screen and flag conditions, combined with any / all. Screen names take the place of URLs on mobile. A group with no conditions activates immediately.
  • Sampling is per group, using the same hash as posthog-js (sessionId + groupId), so web and mobile reach the same decision for a session.
  • Recording starts as soon as any activated group is sampled in. It only waits while no group records and some group is still pending.
  • The lowest minDurationMs among activated groups replaces the v1 minimum duration.
  • $sdk_debug_replay_remote_trigger_matching_config, $sdk_debug_replay_trigger_groups_count and $sdk_debug_replay_matched_recording_trigger_groups match posthog-js.
  • Nothing changes when version is missing or 1.
  • Under React Native, the JS layer evaluates event and screen conditions (that's where events are captured), so this SDK skips those conditions when running under React Native.

The new methods on PostHogRemoteConfig sit on an @PostHogInternal class, so no public API changes.

sdk-specs session-replay-ingestion-controls currently describes v2 as web-only. Happy to add the mobile behaviour there in a follow-up.

Companion PRs for iOS, React Native and Flutter are linked in the Knit block above. I'd especially like a sanity check on the union rule and the React Native split.

💚 How did you test it?

  • Unit tests for parsing, status combining, the sampling hash (vectors computed from the posthog-js helper), property filters, the union rule, minimum duration, session rotation and sample-rate changes. ./gradlew :posthog:test :posthog-android:testDebugUnitTest apiCheck spotlessCheck passes.
  • End to end with posthog-android-sample on an Android 15 emulator, pointed at a local mock PostHog server (POSTHOG_HOST) that served two groups: one on start_replay_trigger_2 with sampleRate: 0, one on start_replay_trigger_1 with sampleRate: 1. Tapping the sample's buttons:
    • before any trigger: no $snapshot uploads, $recording_status: disabled, matched_recording_trigger_groups: []
    • start_replay_trigger_2: still no snapshots; the group reports matched: true, sampled: false
    • start_replay_trigger_1: snapshots start uploading within a second, $recording_status: active, both groups reported with the right sampled value

📝 Checklist

  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • I updated the docs if needed.
  • No breaking change or entry added to the changelog.

If releasing new changes

  • Ran pnpm changeset to generate a changeset file

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

  • Driven by me in Ivaldi, my agent workspace. Claude Code (Opus 5.5) planned, reviewed and integrated the work; OpenCode (GLM 5.3) wrote the first implementation from a contract taken from the posthog-js code.
  • The feature spans four repos, so I ran it as one Knit bundle: the Android, iOS, React Native and Flutter changes were built, tested and versioned together. All four diffs side by side on Svartal.

Evaluate the v2 trigger groups from the sessionRecording remote config:
per-group event, screen and flag conditions combined with any/all,
per-group sampling with the same hash as posthog-js, and recording
when any activated group is sampled in. The lowest minDurationMs among
activated groups replaces the v1 minimum duration, and the
$sdk_debug_replay_* properties report the matched groups. Configs
without version 2 keep the v1 behaviour.

Assisted-by: OpenCode/glm-5.3
Assisted-by: Claude Code/claude-opus-5-5

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Session replay: support v2 trigger groups (conditional recording)

1 participant