From ddf18d384b1104d0bdf253c6bfdca54a3bc265d6 Mon Sep 17 00:00:00 2001 From: aliferous3 Date: Wed, 30 Sep 2026 01:16:34 +0400 Subject: [PATCH] fix: emit pageviews on popstate for anonymous sessions too useRoute only mounts inside the authenticated App, so back/forward navigation while logged out produced no $pageview. A boot-level popstate listener now emits for every session; pathname dedupe collapses the overlap with useRoute's own listener. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- src/main.tsx | 11 +++++++++-- test/posthog-analytics.test.mjs | 5 ++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main.tsx b/src/main.tsx index cfd549c..1608dc6 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -172,8 +172,15 @@ function Root() { // no-ops without a configured token; sends only allowlisted custom events // through the same-origin /rly proxy. The initial sanitized $pageview // emits once the SDK is ready; client-side route changes emit from -// useRoute, deduped on pathname. -void initAnalytics().then(() => capturePageview()).catch(() => {}); +// useRoute, deduped on pathname. The boot-level popstate listener covers +// back/forward for anonymous sessions too (useRoute only mounts inside the +// authenticated App) — pathname dedupe collapses the overlap. +void initAnalytics() + .then(() => { + capturePageview(); + window.addEventListener('popstate', () => capturePageview()); + }) + .catch(() => {}); createRoot(document.getElementById("root")!).render( diff --git a/test/posthog-analytics.test.mjs b/test/posthog-analytics.test.mjs index 21916d6..78c0e48 100644 --- a/test/posthog-analytics.test.mjs +++ b/test/posthog-analytics.test.mjs @@ -509,7 +509,10 @@ test('facade dedupes pageviews and gates on the public host', () => { test('pageview wiring: boot emit once, route changes and popstate covered', () => { const main = src('src/main.tsx'); - assert.match(main, /initAnalytics\(\)\.then\(\(\) => capturePageview\(\)\)/); + assert.match(main, /initAnalytics\(\)[\s\S]*?capturePageview\(\)/); + // boot-level popstate covers back/forward even before the authenticated + // App mounts; useRoute's own listener dedupes against it on pathname. + assert.match(main, /addEventListener\('popstate',[\s\S]*?capturePageview\(\)/); const pages = src('src/pages.ts'); // navigate + popstate each emit — dedup in capturePageview collapses // same-path repeats (StrictMode, hash/range-only history entries).