Replayborg
Replayborg

Replayborg documentation

Self-hosted session replay for WordPress. Watch how visitors actually use your site — the pages they moved through, where they clicked, how long they stayed — with every recording captured by your own site and stored in your own database.

What Replayborg is

Analytics tells you that a page was visited. A session replay tells you what happened on it: where the visitor's attention went, which link they hovered over twice and did not click, the form field they filled in and then cleared, the point at which they left. It is the difference between a number and a story.

Replayborg records those visits with rrweb, which captures the page as a stream of DOM changes rather than as video — a recording is a few dozen kilobytes, not a few dozen megabytes — compresses each batch, and writes it into your WordPress database.

Nothing leaves your site. There is no external service, no API key, no account, and no request to any host but your own. If you can reach the recordings, it is because they are sitting in your database. This is the whole reason the plugin exists: the well-known session replay products are all SaaS, which means handing your visitors' browsing to a third party.

What ships in 1.0

Session recordingVisits captured and GZIP compressed into your database
Session replayPlay, pause, ±10s, 1×–8×, skip-idle, page-marked scrubber
Pages visitedTime on page, clicks, share of the session, entry and exit
Signed-in visitorsSessions attributed to the WordPress user
Filtering and sortingDevice, signed-in status, date range, URL
Traffic sourceReferrer and UTM parameters captured with the visit
RetentionOld recordings removed daily, automatically
Privacy controlsInput masking on by default, blocking, consent gate

Heatmaps, funnels, error tracking, frustration detection and visitor profiles are not in this release. They are the obvious next modules, and the plugin is built so they can arrive without disturbing what you already have — see Hooks for the module rule that makes that safe.

Install

Requirements: WordPress 6.4+ and PHP 8.2+, on whatever database WordPress itself runs on.

  1. Search for SB Replayborg in Plugins → Add New, or install it from the WordPress.org plugin directory.
  2. Activate it through the Plugins menu.
  3. Open Replayborg in the admin menu.

The directory lists it as SB Replayborg — SB for Stackborg, who publish it. Everywhere you actually use it, in the admin menu and on its screens, it is Replayborg.

That is the whole setup. There is nothing to configure before it works: activating it prepares its storage, schedules the daily cleanup, and starts recording. The defaults are chosen so that the first thing you do — opening your own site to check — produces a recording you can watch.

Your first recording

  1. Open your site's front end in a normal browser window and click around a few pages.
  2. Wait a moment. Frames are flushed every five seconds and again when the page is closed.
  3. Go to Replayborg in wp-admin. The visit is in the list.

No recording appeared? The most common causes are a caching plugin serving a page without the recorder, an ad blocker, or a page that was open for less than a second. See Troubleshooting.

The session list

One row per visit. Each cell carries two lines — the value, and the fact that qualifies it — so you can tell a bounced mobile visit from a long desktop one without opening anything.

ColumnWhat it tells you
VisitorName and avatar for signed-in users; the anonymous visitor id otherwise
JourneyThe page the visit started on, and the page it ended on
SourceWhere the visit came from — a campaign parameter, a referring site, or direct
DeviceDesktop, mobile or tablet, with the screen size that was recorded
DurationHow long the visit lasted
PagesHow many pages the visitor moved through
RecordedWhen it happened, in your site's timezone and date format

Columns drop out as the screen narrows, in order of how much each one adds beyond the rest of the row. Above the table, four figures summarise the page you are looking at — and they say on this page rather than pretending to be site-wide averages, because the list is paginated and a number that quietly means something narrower than its label is worse than no number.

Everything is in the URL

The page you are on, the sort, and every filter live in the address bar. Open a recording and press Back and you return to the same page of the same filtered list. Bookmark a view, or send it to a colleague as a link, and they see what you saw.

Filtering and sorting

FilterOptions
SearchAny part of the entry or exit URL — type and pause, no button to press
DeviceDesktop, mobile, tablet
VisitorSigned in, or anonymous
Date rangeToday, yesterday, last 7 / 30 days, this month, or a custom range
SortDuration, pages, or when it was recorded — either direction
Per page20, 50 or 100 rows

Date filters are calendar dates in your site's timezone. That matters more than it sounds: recordings are stored in UTC, so on a UTC+6 site an unconverted "today" would lose everything recorded before 6am and gain the previous evening. Replayborg converts the range before it queries.

Active filters appear as chips under the controls. Each can be removed on its own, or all at once.

Watching a session

Click any row. The player rebuilds the page as the visitor saw it and replays what they did.

ControlWhat it does
Play / pauseThe frame itself is also the play button — click the video
± 10 secondsSkip back or forward
Speed1×, 2×, 4×, 8× on one cycling control
Skip idleJump over the stretches where nothing happened
ScrubberMarked with the point each page of the visit began — click a marker to jump there
ViewDefault, theater (full page width), or full page — Escape leaves full page

The recording's own aspect ratio is read from its first frame, so a phone capture is shown as a phone rather than letterboxed into a 16:9 box.

Pages visited

Below the player, every page of the visit in order:

Clicking any row seeks the player to that page. So does clicking a bar in the activity strip on the right, which shows where in the recording the clicking actually happened.

Who the visitor was

If a visitor is signed in to WordPress, the session is attributed to their user account — avatar, display name, and a link to their profile. If they sign in during the visit, the session is claimed for them at that moment and never re-assigned afterwards.

Anonymous visitors get a random visitor id, generated in the browser and stored there. It is not linked to an identity, it is not shared between sites, and it is the only thing that ties two visits from the same browser together.

Settings and defaults

This release ships no settings screen. The values below are stored in the sb_replayborg_settings option and can be changed with WP-CLI, a small snippet, or any options editor.

KeyDefaultWhat it does
recording_enabledtrueSwitch recording off without deactivating the plugin
mask_inputstrueReplace typed text before it leaves the browser
block_selectoremptyCSS selector for elements that are never recorded
sample_rate100Percentage of visits to record
max_session_minutes30Recording stops after this long
consent_requiredfalseWait for a consent signal before recording
exclude_rolesemptyComma-separated role slugs that are never recorded
retention_days30How long recordings are kept
wp option patch update sb_replayborg_settings retention_days 14
wp option patch update sb_replayborg_settings exclude_roles administrator,editor

Nothing is excluded by default, including administrators. The obvious default would be to skip them — their own browsing skews the figures — but a rule you can neither see nor switch off is indistinguishable from the plugin being broken, and the first thing anyone does is open their own site to check that recording works. Exclude yourself once you have seen it work.

Privacy

Session recordings are personal data in most jurisdictions, including under the GDPR. Running this plugin makes you the controller of that data. Replayborg is built to make that manageable, but it cannot make the decision for you.

What the plugin does about it

What is still yours to do

The full privacy policy — what the plugin records, what Stackborg receives (nothing), what you are responsible for as the site owner, and wording you can adapt for your own policy — is at Privacy policy.

This documentation page itself requests nothing from any other server — no fonts, no images, no trackers — sets no cookies and collects nothing about you. The one script on it is a dozen inline lines that highlight the section you are reading.

Retention and storage

Recordings live in tables of the plugin's own inside your WordPress database, and the frames are compressed before they are written — rrweb output is repetitive JSON, and roughly 90% of it disappears.

As a rough guide, a five-page visit is a few hundred kilobytes; a small site keeping 30 days is usually tens of megabytes rather than gigabytes. Shorten the window if that matters on your host.

Performance

Full-page caching is fine. Recording is designed to keep working when a page is served from cache, which is where plugins that depend on per-request tokens usually break.

Hooks

sb_replayborg_should_record — filter

The last word on whether a page view is recorded. It runs before the recorder is enqueued, so returning false means the script is never sent — not that it is sent and does nothing.

// Do not record administrators.
add_filter( 'sb_replayborg_should_record', function ( bool $record ): bool {
    return current_user_can( 'manage_options' ) ? false : $record;
} );

// Never record checkout, whatever else is true.
add_filter( 'sb_replayborg_should_record', function ( bool $record ): bool {
    return is_page( 'checkout' ) ? false : $record;
} );

sb_replayborg_cleanup — action

The daily retention job. Fire it by hand to test retention without waiting:

do_action( 'sb_replayborg_cleanup' );

Options

Settings live in one option, sb_replayborg_settings, whose keys are the ones in Settings and defaults. The plugin keeps three more of its own for the installed version and which modules are switched on. All of them are removed when the plugin is deleted.

The module rule

Every feature is a module that declares the tables it owns, the REST controllers it contributes and what the recorder should collect for it. The registry boots only the ones switched on — and disabling a module never drops its tables. That constraint is what makes it safe to add features later to sites that already have recordings: existing installs get the feature, and turning it back off does not destroy what it collected.

FAQ

Does any data leave my site?

No. There is no external service, no API key and no account. Recordings are written to your database and read back from it.

Does it work with caching plugins?

Yes, and it is built for them. Nothing the recorder needs is embedded per request, so a page served from cache records exactly like an uncached one.

Will it slow my site down?

One script on the front end, frames batched and flushed every five seconds, and a beacon on unload. See Performance.

Can I stop recording myself?

Yes — set exclude_roles, or use the sb_replayborg_should_record filter. Nothing is excluded by default so that your first check actually produces a recording.

Are passwords recorded?

No. Input masking is on by default and replaces typed text in the browser, before anything is sent.

How much database space does it use?

Frames are GZIP compressed; a typical five-page visit is a few hundred kilobytes. Retention defaults to 30 days and is configurable.

Does uninstalling delete my recordings?

Deactivating does not. Deleting the plugin does — its tables and its settings are removed, and nothing is left behind.

Can I record only some visitors?

Yes — sample_rate records a percentage of visits, and the filter above can decide per page view.

Does it work on multisite?

Each site in a network keeps its own recordings and its own settings, and each is read from that site's own admin. There is no network-wide screen in this release, so a network administrator sees one site at a time.

Troubleshooting

No recordings appear

  1. Open your site in a browser and view source. If recorder.js is not there, something is preventing the enqueue: a filter, an excluded role, a sample rate below 100, or the consent gate waiting for a signal that never arrives.
  2. Check the browser console for blocked requests — ad blockers and strict privacy extensions sometimes stop the beacon.
  3. Visit more than one page and stay for a few seconds. Very short visits may end before the first flush.
  4. If a caching or optimisation plugin combines and defers scripts, try excluding recorder.js from it.

Recordings are there, but signed-in visitors show as anonymous

Attributing a visit to a WordPress user depends on the page being served fresh to that user. If a caching layer is serving logged-in visitors a cached page, WordPress cannot recognise them and the visit is filed as anonymous — exclude logged-in users from full-page caching, which most caching plugins do by default.

The player shows a blank frame

A recording needs its first full snapshot to replay. If the visit began before the recorder finished starting — a very fast bounce, usually — there is nothing to rebuild, and the screen says so rather than showing an empty box.

Old recordings are not being deleted

Retention runs on WP-Cron, which only fires when the site gets traffic. On a quiet site, use a real cron: wp cron event run sb_replayborg_cleanup.

Timestamps look wrong

Every timestamp on these screens uses Settings → General — timezone, date format and time format. Recordings are stored in UTC and converted for display. If the site's timezone is unset, WordPress reports UTC and that is what you will see.

Support

Write to us. One address, answered by the people who build it:

support@stackborg.com

Security issues go to security@stackborg.com instead — please report those privately rather than in public, and give us time to ship a fix before describing the problem anywhere else.

What to include

These five things turn a report into a fix, and their absence turns it into three rounds of questions:

Please do not send database dumps or exported recordings — they contain your visitors' personal data, we do not need them to help, and we would rather not hold them.

Everything on this site

PageWhat is on it
DocumentationThis page — install, first recording, the session list, filtering, the player, pages visited, settings, privacy controls, retention, performance, hooks, the REST API, building the JavaScript, FAQ and troubleshooting
Privacy policyWhat is recorded, where it is stored, what we never receive, what you are responsible for as the site owner, and wording you can adapt for your own policy
The pluginReplayborg on the WordPress.org directory — download, ratings, version history and the changelog

Straight to a section