Skip to content
GDPR compliant. Hosted in DE.
14-day free trial →

Session recording

See your site through your visitors' eyes. Mouse movements, clicks, scrolls and DOM mutations are recorded as space-efficient rrweb events and replayed in a built-in player — fully cookieless with automatic privacy masking of sensitive fields. Business plan (EUR 29/month) and above.

# How to enable recording

Primary path: Analytics → Settings tab
In the dashboard under Analytics → Settings, toggle session recording on. The change is persisted in the tracker server configuration and takes effect within 5 minutes (HTTP cache) for all visitors — no re-embed, no deploy. The same place configures sample rate, mask selectors and URL exclusions. See Tracker settings.

Override via HTML attribute (fallback)

If you prefer to pin tracker config in HTML (e.g. multiple sub-domains share the same site ID but only one should record), the data-record="1" attribute on the script tag overrides the server config:

<script defer src="https://api.xictraq.com/t.js"
        data-site="YOUR_SITE_ID"
        data-record="1"></script>
<noscript><img src="https://api.xictraq.com/api/px?s=YOUR_SITE_ID" alt="" width="1" height="1" style="position:absolute;left:-9999px" referrerpolicy="no-referrer-when-downgrade"></noscript>

We recommend the server configuration as the default — it is live-adjustable and applies instantly. There is no JavaScript variable like cfg.rec — configuration runs exclusively via the Settings tab or data-* attributes.

# Recording player

Recordings → Play session
View in demo account →
Session #r_8f2a91d4
Cologne, DE · Chrome 121 · macOS · 4 pageviews · 3:42 duration
Rage click Dead click
Selects the point in the recording to play from. The arrow keys move it in small steps.
00:001:0203:42
Plays the recording at normal, double or quadruple speed.
Pageview
Click
Rage click
Error

# Features

rrweb-based (open source)

Instead of capturing image frames (heavy and privacy-questionable), rrweb records DOM mutations + mouse events — typical storage: 2–8 KB per second. The entire recording is replayed in the browser, the real HTML/CSS stack of the site is visible.

Privacy by default

Masking applies in three layers, all at the tracker — sensitive data never even leaves the visitor browser in clear text:

  • maskAllInputs — all input fields are masked by default; typed values never reach the recording.
  • auto-redaction in text nodes: credit-card numbers (13–19 digits, Luhn-checked) and IBANs are automatically replaced with • — even when they appear as plain text on confirmation or account pages. Deliberately conservative so ordinary numbers/IDs survive.
  • opt-in masking: regions marked with data-xictraq-mask or custom CSS selectors (tracker settings) are fully masked. data-xictraq-block excludes an element from recording entirely (blockSelector).

Auto-tagging: rage clicks, dead clicks, errors

A cron (/cron/tag-recordings) analyses every completed recording via heuristic and attaches tags (session_recordings.tags column, JSON array):

  • rage_click — 3+ clicks within 2 s in a 30 px radius of the first click
  • dead_click — click without DOM mutation and without page change within 1.5 s (broken buttons / broken onclick)
  • error — window.onerror or unhandledrejection during the session — tracker writes it as rrweb custom event into the recording stream so the cron can find it

Tags appear as badges in the recordings list at Analytics → Recordings & Tests.

Linked to form events

Form events and recordings carry the same daily identifier of the visit (session_hash); this lets you match them to each other. There is no shared recording ID: the recording identifier is only sent with the recording chunks to /api/p/r. The recording list shows problematic sessions directly via the auto-tags. Freely configurable SQL-style filters (“sessions with form view without submit” etc.) are not yet self-service — on request we set up custom queries for you.

First-party hosting (no 3rd-party CDN)

The rrweb engine and player CSS are NOT loaded from the rrweb CDN, but from the API origin (api.xictraq.com or your first-party proxy) with obfuscated filenames (rx.js, rxp.js, rxp.css). Standard EasyPrivacy filterlists would block “rrweb.min.js” by filename — our variant goes undetected.

Consent-gated start (no auto-recording)

Even when recording is enabled in the settings, capture does NOT start automatically on load. It waits for the consent signal from your page or consent tool:

xictraq.consent('granted');   // startet Recording (wenn aktiviert)
xictraq.consent('denied');    // stoppt Recording
xictraq.record('start');      // Recording gezielt ein-/ausschalten
xictraq.record('stop');

Only when both activation AND consent are present does the rrweb engine (rx.js) load and capture begin. The recording ID lives in the tab sessionStorage and applies per recording: after 30 minutes without a recorded event (changes to the page count as well) and with the first page load after midnight (UTC), a new recording begins with a new recording ID (from tracker version 61). No cookie; sessionStorage is bound to the tab and the website.

Chunk transport & crash-safe flushing

rrweb events are buffered and sent in chunks to /api/p/r — throttled so even long sessions stay lean:

  • flush once 60 events are buffered, plus every 10 seconds, plus on pagehide (final chunk; it is omitted after more than 30 minutes without a recorded event) and when the tab goes to the background.
  • sampling: mouse moves every 100 ms, scroll every 150 ms, inputs as last value only — cuts volume without losing replay fidelity.
  • server-side cap: a single recording file is capped at 10 MB so outliers cannot flood disk. Once the cap is reached, no further recording begins in that tab, not even after a pause or a change of day.
  • external stylesheets are inlined into the rrweb snapshot at ingest (same-host only, SSRF-safe) — so replay stays visually correct even after the site redeploys with newly hashed asset URLs.

Storage & retention

Sessions with no new chunk for 30 minutes are marked complete by /cron/compress-recordings (catches browser crashes, abrupt tab closes and recordings after the idle period, for which no pagehide flush arrives). Completed sessions older than one hour are compressed by the same cron to .ndjson.gz (~70 % space saved, max 200 per run). Sample rate is configured by you in Analytics → Settings (1–100 %, applies to all tracker features). For privacy reasons (Art. 5(1)(e) GDPR, storage limitation) recordings have a fixed cap of 90 days — independent of plan and decoupled from the otherwise unlimited aggregate analytics retention. If your plan analytics retention is shorter than 90 days, that shorter window applies. The "Extended data retention" add-on extends aggregate analytics retention but does NOT lift the 90-day cap for recordings.

Recording is opt-in
Unlike pageviews and form analytics, session recording is off by default. Enable it deliberately via Analytics → Settings, call xictraq.consent("granted") from your CMP and mention recording in your privacy policy — even though no cookies are set, recording is legally more sensitive than pure aggregate stats.

Frequently asked questions

Session recording is available from the Business plan (Business and Agency). For privacy reasons recordings have a fixed cap of 90 days — independent of plan and decoupled from aggregate analytics retention. Completed sessions are compressed to .ndjson.gz hourly. The "Extended data retention" add-on (EUR 9/month) extends aggregate analytics retention but does not lift the 90-day cap for recordings.
Availability
Session recording is available from the Business plan (EUR 29/month) and is also included in the Agency plan. Server-side plan gating guards every recording endpoint — capture and replay are not accessible without an eligible plan.
Start in 60 seconds

Let XICTRAQ watch your website.

Permanent free plan available. No credit card, no installation, no hidden fees.