SIGN IN SIGN UP

feat(browser): add granular SPA pageview options (#4418)

* fix(browser): capture SPA pageviews on query-string and hash-only navigations

`HistoryAutocapture` only compared `location.pathname`, so pushState/replaceState/popstate navigations that changed only the query string or hash were silently dropped. Now the full `pathname + search + hash` is compared (respecting `disable_capture_url_hashes`), matching how GA4's history-based page_view tracking works.

Generated-By: PostHog Code
Task-Id: 1507d9c8-939a-49b0-a898-5c01a99e39cf

* chore: add changeset for SPA pageview query/hash fix

Generated-By: PostHog Code
Task-Id: 1507d9c8-939a-49b0-a898-5c01a99e39cf

* chore(browser): update mangled property names for history-autocapture rename

CI's "Write mangled property names" check flagged the renamed `_lastPathname` -> `_lastLocation` field and new `_getComparableLocation` method.

Generated-By: PostHog Code
Task-Id: 1507d9c8-939a-49b0-a898-5c01a99e39cf

* fix(browser): capture hash-only navigations via hashchange listener

Direct `location.hash` changes and in-page anchor navigations fire
`hashchange`, not `popstate` and not the patched `pushState`/`replaceState`,
so `HistoryAutocapture` never observed them. Because this PR added the hash to
the compared location, an unobserved hash change left `_lastLocation` stale:
a later same-URL history call then looked like a change and captured a false
`$pageview`, and the mirror Back traversal missed the real one.

Add a `hashchange` listener that captures the navigation and keeps
`_lastLocation` in sync (removed in `stop()`), consistent with the PR's own
decision that hash-only changes warrant a `$pageview` and with how
`surveys.tsx` already listens to `hashchange` for hash-based routing. It
respects `disable_capture_url_hashes` automatically since
`_getComparableLocation` strips the hash. Adds tests for the capture, the
no-op-dedup regression, and the disabled-hash case.

Generated-By: PostHog Desktop
Task-Id: f18e89e1-9718-4c70-bd9c-4e5833f08bd9

* feat(browser): add granular SPA pageview options

* refactor(browser): skip inactive history monitoring

---------

Co-authored-by: posthog[bot] <206114724+posthog[bot]@users.noreply.github.com>
Co-authored-by: Manoel Aranda Neto <marandaneto@gmail.com>
Co-authored-by: Dustin Byrne <dustin@posthog.com>
Co-authored-by: Anna Garcia <anna.g@posthog.com>
P
posthog[bot] committed
be2161d68946b30d27d7a0a5c2cb5671b04d5ac0
Parent: 4feb70c
Committed by GitHub <noreply@github.com> on 8/24/2026, 12:21:32 PM