diff --git a/.changeset/silver-lemons-behave.md b/.changeset/silver-lemons-behave.md new file mode 100644 index 0000000000..39d518f0ba --- /dev/null +++ b/.changeset/silver-lemons-behave.md @@ -0,0 +1,5 @@ +--- +'posthog-js': patch +--- + +Fix delayed event flushing after `opt_in_capturing()` (fixes cookieless mode needing reload before events are captured) diff --git a/packages/browser/src/__tests__/cookieless.test.ts b/packages/browser/src/__tests__/cookieless.test.ts index bd5ddefc31..92063b98df 100644 --- a/packages/browser/src/__tests__/cookieless.test.ts +++ b/packages/browser/src/__tests__/cookieless.test.ts @@ -310,5 +310,32 @@ describe('cookieless', () => { expect(beforeSendMock.mock.calls[3][0].properties.$cookieless_mode).toEqual(true) expect(posthog.sessionRecording).toBeFalsy() }) + + it('should restart autocapture after opt_in_capturing in cookieless mode', async () => { + const { posthog } = await setup({ + cookieless_mode: 'on_reject', + }) + + // Mock the autocapture startIfEnabled method + const mockStartIfEnabled = jest.fn() + const originalStartIfEnabled = posthog.autocapture?.startIfEnabled + if (posthog.autocapture) { + posthog.autocapture.startIfEnabled = mockStartIfEnabled + } + + // Clear any previous startIfEnabled calls + mockStartIfEnabled.mockClear() + + // Opt in + posthog.opt_in_capturing() + + // Autocapture should be restarted immediately after opt-in + expect(mockStartIfEnabled).toHaveBeenCalledTimes(1) + + // Restore original method + if (posthog.autocapture && originalStartIfEnabled) { + posthog.autocapture.startIfEnabled = originalStartIfEnabled + } + }) }) }) diff --git a/packages/browser/src/posthog-core.ts b/packages/browser/src/posthog-core.ts index 72cabc87ba..21b5cbc8b1 100644 --- a/packages/browser/src/posthog-core.ts +++ b/packages/browser/src/posthog-core.ts @@ -2925,6 +2925,9 @@ export class PostHog { this.surveys.loadIfEnabled() } + // Restart autocapture after opting in + this.autocapture?.startIfEnabled() + // Don't capture if captureEventName is null or false if (isUndefined(options?.captureEventName) || options?.captureEventName) { this.capture(options?.captureEventName ?? '$opt_in', options?.captureProperties, { send_instantly: true })