Skip to content

feat(replay): capture SPA route changes as navigation events#7

Merged
DorianOuvrard merged 2 commits into
mainfrom
feat/spa-navigation-capture
Jun 25, 2026
Merged

feat(replay): capture SPA route changes as navigation events#7
DorianOuvrard merged 2 commits into
mainfrom
feat/spa-navigation-capture

Conversation

@DorianOuvrard

Copy link
Copy Markdown
Contributor

What

rrweb only emits a META event on full page loads, so client-side route changes in SPAs were never recorded and downstream page segmentation saw a whole session as a single page.

The replay module now installs a navigation watcher (inside the lazy rrweb-import boundary) that:

  • patches history.pushState/replaceState and listens for popstate,
  • emits a stable navigation rrweb custom event ({ href, title? }) on each real URL change,
  • dedupes on the last emitted href,
  • survives idle session rotation (dedup baseline reset so each rotated session re-emits its entry URL),
  • carries the genuine original on each wrapper so a re-install after a failed teardown cannot stack,
  • is skipped in cross-origin iframes; every path fails open.

Event contract (stable)

  • tag: "navigation"
  • payload: { href: string, title?: string }href is location.href, title is document.title when non-empty.

Tests

249 vitest tests pass (8 navigation-watcher cases incl. rotation baseline reset + anti-stacking, both proven by mutation). type-check + build green.

Scope

SDK capture only. Backend distiller wiring (treating navigation events and appending to pages_visited) is tracked as the #889 workstream 3 in the vulk-corp/bworlds monorepo and done separately.

Bumps to 1.12.0 (minor) + CHANGELOG. Adds a local yalc testing runbook to CLAUDE.md.

🤖 Generated with Claude Code

DorianOuvrard and others added 2 commits June 24, 2026 11:32
rrweb only emits a META event on full page loads, so client-side route
changes were never recorded and downstream page segmentation saw a whole
SPA session as a single page.

The replay module now patches history.pushState/replaceState (neither
fires natively) and listens for popstate, emitting a stable `navigation`
rrweb custom event ({ href, title? }) on each real URL change. Deduped on
the last emitted href. Survives idle session rotation (dedup baseline reset
so each rotated session re-emits its entry URL). Each wrapper carries the
genuine original so a re-install after a failed teardown cannot stack
wrappers. Skipped in cross-origin iframes; every path fails open.

Backend distiller wiring is tracked separately (#889 workstream 3).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Document the SDK-side workflow for linking an unreleased launchkit build
into a consumer app with yalc (build, yalc publish, yalc push, revert), and
point to the full consumer-side runbook in the monorepo. Closes the gap
where launchkit had no local-publish docs in its own CLAUDE.md.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@DorianOuvrard DorianOuvrard merged commit 0098101 into main Jun 25, 2026
2 checks passed
@DorianOuvrard DorianOuvrard deleted the feat/spa-navigation-capture branch June 25, 2026 08:30
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.

1 participant