On this page

Cross-origin iframe recording

The Session Replay Browser SDK can capture DOM changes inside cross-origin <iframe> elements and merge them into the parent page's replay stream. Both the parent page and each child iframe page must load the SDK with crossOriginIframes.enabled: true.

This article covers configuration, privacy behavior, limitations, and troubleshooting.

Browser SDK only

Cross-origin iframe recording applies to the Session Replay Browser SDK Plugin and Session Replay Standalone SDK. Mobile Session Replay SDKs don't support this feature.

How it works

When you enable cross-origin iframe recording on the parent page, the SDK:

  1. Watches for <iframe> elements added to the DOM.
  2. Sends start and stop signals to child frames over postMessage.
  3. Relays child rrweb events into the parent replay stream so the replay viewer can reconstruct both frames from a single session.

The child SDK detects when it runs inside an iframe and waits for a start signal from the parent before it begins recording.

Setup

Load the Session Replay SDK on both the parent page and each child iframe page you want to capture.

Parent page

javascript
import * as sessionReplay from "@amplitude/session-replay-browser";

sessionReplay.init("API_KEY", {
  deviceId: "DEVICE_ID",
  sessionId: SESSION_ID,
  sampleRate: 1,
  crossOriginIframes: {
    enabled: true,
    coordinateChildren: true,
  },
});

If you use the Browser SDK plugin, pass the same options to sessionReplay.plugin():

javascript
import * as amplitude from "@amplitude/analytics-browser";
import { sessionReplayPlugin } from "@amplitude/plugin-session-replay-browser";

const replay = sessionReplayPlugin({
  crossOriginIframes: {
    enabled: true,
    coordinateChildren: true,
  },
});

amplitude.add(replay);
amplitude.init("API_KEY", { deviceId: "DEVICE_ID" });

Child iframe page

Initialize the SDK with the same apiKey, deviceId, and sessionId as the parent. Enable cross-origin iframes, but don't set coordinateChildren on the child:

javascript
import * as sessionReplay from "@amplitude/session-replay-browser";

sessionReplay.init("API_KEY", {
  deviceId: "DEVICE_ID",
  sessionId: SESSION_ID,
  sampleRate: 1,
  crossOriginIframes: { enabled: true },
});

Pass sessionId and deviceId to the child through the iframe URL query string when you set the iframe src.

Configuration options

Privacy

The child page's rrweb instance performs its own DOM serialization. The parent's privacy config (mask levels, block selectors, and so on) doesn't automatically apply inside the iframe. Configure privacy settings independently on each child page.

Limitations

  • Third-party iframes (for example, Stripe, Google Maps, or YouTube) can't be captured. You control only pages where you install the Session Replay SDK.
  • coordinateChildren: false opts out of the parent coordinator. In this mode, the child SDK doesn't start recording until you manage its lifecycle directly.
  • Same-origin iframes don't require cross-origin configuration, but enabling crossOriginIframes on both pages still works.

Validate your setup

  1. Confirm the parent and each child page load the Session Replay SDK with crossOriginIframes.enabled: true.
  2. Use the same apiKey, deviceId, and sessionId on both pages.
  3. Add or navigate to the child iframe after the parent SDK initializes.
  4. Interact inside the iframe, then open the session in Amplitude's replay viewer.

For local cross-origin testing, serve the parent and child from different origins (different ports or hostnames). A public HTTPS parent can't embed an http://localhost child because of mixed content and browser Local Network Access restrictions.

Troubleshooting

The iframe is blank in the live page

The iframe is blank in the replay viewer

Was this helpful?