Add the recorder
One script tag records every page it is on. It works on any site, with any framework or none.
The script tag
Replace replay.example.com with the domain of your Replayowl server:
<script src="https://replay.example.com/recorder.js"
data-endpoint="https://replay.example.com/api/ingest" defer></script>
Put it on every page you want recorded. Page loads in the same tab within 30 minutes are merged into one session.
Starting from code
Leave out data-endpoint and start the recorder yourself, for example after the visitor has accepted your consent banner:
ReplayOwl.start({ endpoint: "https://replay.example.com/api/ingest" });
Stop it with ReplayOwl.stop(). Anything still waiting to upload is sent when it stops.
Attaching your user IDs
To find a session by the account that was signed in, pass your own user ID. Any of these work:
<script src="https://replay.example.com/recorder.js"
data-endpoint="https://replay.example.com/api/ingest"
data-user-id="user_8421" defer></script>
ReplayOwl.start({ endpoint, userId: "user_8421" });
ReplayOwl.identify("user_8421");
identify can be called at any time after the script has loaded, including before start. The whole session is attributed to that user, including what happened before the call. An ID is 1 to 128 characters. A session keeps up to five different IDs, so a visitor who switches accounts can be found under each one. The current ID is kept in sessionStorage, so later pages in the same tab carry it.
With defer, the script has not run yet when your inline code runs. Call identify after the script has loaded, for example in its load event, or use data-user-id.
Options
Pass options as fields in ReplayOwl.start({ ... }). The five masking options can also be set on the script tag, written as data-mask-all-text="true", data-mask-all-inputs="false" and so on.
| Option | Default | What it does |
|---|---|---|
maskAllInputs |
true |
Mask every text input |
maskAllText |
false |
Mask all text on the page |
maskEmails |
true |
Mask email addresses in regular text |
maskCardNumbers |
true |
Mask runs of 12 to 19 digits, such as card and account numbers |
maskDigits |
false |
Mask every digit |
sessionTimeoutMin |
30 |
Minutes of inactivity after which the next page load starts a new session |
captureLogs |
true |
Record console.error, console.warn, uncaught exceptions and unhandled promise rejections |
See Masking and privacy for the attributes that mask or hide individual elements.
What gets recorded
- The page: a full snapshot when it loads, then every change. Each node gets a fixed numeric ID, so replays do not depend on CSS selectors that can point at the wrong element after the page changes.
- Styles: same-origin stylesheets are copied into the snapshot, so replays do not depend on your site still serving the same CSS. Rules that CSS-in-JS libraries write straight into the CSSOM,
insertRule, constructed stylesheets andadoptedStyleSheetsare captured too. - Shadow DOM: open shadow roots and their stylesheets, including custom elements that attach a shadow root later.
- Forms: typing, selecting and checking, and values set by scripts, so autofill by form libraries shows up.
- Behaviour: mouse and touch movement, clicks, window and element scrolling, viewport size, focus, tab visibility, media play and pause, and console errors.