feat(session-replay-browser): expose start and stop recording APIs - #1949
Merged
Merged
Conversation
Allow customers to pause and resume session replay capture without tearing down the SDK. start/stop are available on the standalone browser SDK, the analytics plugin, and the unified client. Co-authored-by: Jesse Wang <jxiwang@users.noreply.github.com>
jxiwang
marked this pull request as ready for review
August 21, 2026 18:21
size-limit report 📦
|
Session Replay Browser E2E ResultsDetails
Flaky testschromium › e2e/cross-origin-iframe.spec.ts › cross-origin iframe recording › coordinator sends start signal to dynamically-added child iframe |
Add Playwright tests that mutate the DOM against a live rrweb recorder to prove stop() actually cancels capture and start() resumes it. Also assert the unit path invokes the cancel callback returned by record().
Abort _recordEvents after each await if stop() or shutdown() ran, so a start that already passed getShouldRecord cannot call rrweb record() after the customer paused capture. Co-authored-by: Jesse Wang <jxiwang@users.noreply.github.com>
Ensure stop() during initializeNetworkObservers does not start rrweb, and that a child iframe onStart after stop() is ignored.
Coordinated iframe children wait for a parent start signal on init. After a customer stop()/start() the parent may already be recording and will not send another signal, so start() now begins child recording immediately while still listening for later parent stop/start.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue.
Reviewed by Cursor Bugbot for commit 3d36667. Configure here.
A gated start() was clearing startChildRecordingOnSetup before getShouldRecord() could fail, so coordinated child iframes waited forever for a parent signal that would never be resent.
Properties can become true as soon as targeting matches, before rrweb events are in the current sequence. flush() only drains the track destination, so a one-shot blur plus polling flush() never sends.
bravecod
approved these changes
Aug 27, 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
Exposes
start()andstop()on the Session Replay browser SDK so customers can pause and resume capture without tearing down the SDK.@amplitude/session-replay-browser):sessionReplay.stop()/sessionReplay.start()@amplitude/plugin-session-replay-browser): methods on the plugin instanceclient.sessionReplay().start()/.stop()because that client already returnsAmplitudeSessionReplaystop()cancels the live rrweb recorder (it does not keep observing the DOM), flushes already-captured events, and keeps session id, config, and page listeners in place.start()begins a new rrweb recording. Sampling, targeting, opt-out, and remotecaptureEnabledstill apply. Focus and targeting paths will not auto-restart recording afterstop().In-flight
_recordEvents()that already passedgetShouldRecord()is abandoned afterstop()/shutdown(), so a paused session cannot resume from a stalerecord()call.In coordinated cross-origin child iframes,
init()still waits for a parent start signal, but a customerstart()self-starts capture so resume does not hang if the parent is already recording.This matches the start/stop API already present on the React Native Session Replay SDK.
shutdown()remains the way to fully discontinue collection and remove listeners.Coverage:
stop()invokes the cancel callback returned by rrwebrecord(), and thatstop()during an in-flightrecordEvents()does not start rrwebstart()afterstop()self-starts without a parent signalpackages/session-replay-browser/e2e/start-stop.spec.tsthat mutates the DOM against a live recorder and asserts mutations afterstop()never reach the track APIChecklist