Repository navigation
fix(browser): track page views on replaceState navigation - #2108
Merged
Merged
Conversation
Contributor
size-limit report 📦
|
Contributor
Author
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 58e108b. Configure here.
Mercy811
marked this pull request as ready for review
October 29, 2026 22:11
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
daniel-graham-amplitude
approved these changes
Oct 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes SDK-413: React SPA navigation through
history.replaceState(including React Router'snavigate(path, { replace: true })) currently misses[Amplitude] Page Viewed. Successful URL changes now use the existingtrackHistoryChangesandtrackOnrules. State-only hydration and unchanged-URL replacements stay silent.History wrappers forward the original arguments, receiver, return value, and exceptions. The existing synchronous URL baseline, instance tracking guard, teardown policy, and pending page-view completion behavior are preserved. Regression tests exercise native history calls, filtering, suppression, redirects/Back, failures, wrapper composition, shared page-view IDs, multiple projects, and teardown.
Under
all(also the default), query cleanup and hash changes made withreplaceStatecount as URL changes;pathOnlycontinues to ignore them. Applications that replace URLs can therefore see more page views after adopting the fix. Public usage/reference documentation is tracked separately in SDK-447 for the release.The PR also includes a minimal nuqs SPA under
test-server/nuqs-spa(pnpm dev:nuqs). It reads the API key only fromVITE_AMPLITUDE_API_KEYin the repository.env, uses the US server zone with SDK debug logging, and lets visitors select all (default) or pathOnly before initialization. The SPA controls table has one row per button, including its handler and History API operation, with expected additional page views in the all (default) and pathOnly columns. The page keeps only initialization, a nuqs history selector, and the button/code/expectation table; inspect events in the console, Network panel, or Amplitude project. There are no custom event observers or history instrumentation. Neither.envnor its values are committed.Validation
Node.js 24.10.0 / pnpm 11.28.5:
pnpm install— passed.pnpm build --concurrency 1— passed for all 30 projects; default parallel build attempts stalled locally in Rollup.pnpm docs:check— passed.pnpm lintandpnpm lint:deps— passed.Page-view package build/typecheck and all 48 tests — passed with 100% coverage. The new 15-case regression suite fails against the original implementation (12 failures) and passes with this fix.
pnpm test -- --runInBand --watchman=false --forceExit— passed for all 31 projects on the final full run (prior successful targets reused Nx cache). Watchman is disabled because of local startup permissions;forceExitavoids existing open Jest handles. An earlier full run failed the page-counter test that schedules navigation exactly at its 500 ms session timeout; that test passed isolated reruns with both the fix and the original tracker.pnpm test:examples— blocked by the existing missingjest.setup.examples.jsreferenced by the root script. No example configuration changes are included.Latest
pnpm test --concurrency 1 -- --runInBand --watchman=false --forceExit— passed for all 31 projects (56 of 60 tasks reused Nx cache); serial execution avoids the local parallel Rollup stalls.nuqs app production build, formatting/dependency checks, and browser verification of initialization and both tracking modes — passed. Browser initialization also verified with the repository
.envAPI key.Checklist
Note
Medium Risk
Changes global History API monkey-patching and page-view volume for replace-based SPA navigation; well covered by new tests but affects production autocapture behavior.
Overview
Fixes missing
[Amplitude] Page Viewedevents when SPAs navigate viahistory.replaceState(e.g. React Routernavigate(..., { replace: true })or nuqs query updates).The page-view plugin now proxies both
pushStateandreplaceState. ForreplaceState, it only runs the existing history handler whenlocation.hrefactually changes, so router hydration and state-only replacements stay silent.pushStatestill always goes through the handler;trackHistoryChanges,trackOn, deduplication, and teardown behavior are unchanged—apps onallmay see more page views for query/hashreplaceStateupdates.Adds a
history.test.tsregression suite and atest-server/nuqs-spamanual harness (pnpm dev:nuqs, rootnuqsdevDependency) wired out of the shared Vite test-server build.Reviewed by Cursor Bugbot for commit 58e108b. Configure here.