Documentation
Web-SDK snippet and configuration
Snippet#
The current version is in the repository: github.com/rockstat/web-sdk/snippet. Step-by-step installation is described in the guide.
<script>
!function (w, d, st, cn, hs, lj, rst, se, he) {
if(w.rstat4) return; rst = w.rstat4 = function () {
var a = Array.prototype.slice.call(arguments);
a.length && a[0] === cn && rst._a(Object(a[1]));
return rst.doCall ? rst.doCall.call(rst, a) : rst._q.push(a) && 0; };
rst.push = rst; rst._sv = '5.2.1'; rst._q = [];
rst._jsl = function (src) {
se = d.createElement(st); se.async = !0; se.src = src;
he = d.getElementsByTagName(st)[0]; he.parentNode.insertBefore(se, he); };
rst._a = function(conf){
rst._host = conf.server; rst._prefix = conf.pathPrefix || '';
rst._host && rst._jsl(hs+rst._host+rst._prefix+lj); }
}(window, document, 'script', 'configure', 'https://', '/lib.js');
// --- configuration ---
rstat4('configure', {
server: 'YOUR_SUBDOMAIN.DOMAIN' // <<< replace
});
rstat4('page'); // <<< remove if needed
</script>
How the loader works#
- Creates the global
rstat4function with a_qqueue. Inserting the snippet again is safe: ifwindow.rstat4already exists, the loader does nothing. - Every
rstat4(...)call made before the library loads is pushed onto the queue and returns0. - Calling
rstat4('configure', { server })kicks off the asynchronous load ofhttps://<server><pathPrefix>/lib.js. - The library drains the queue, initializes on
DOMContentLoaded, and runs the accumulated calls. After that,rstat4(...)works directly and returns the method's result.
rst._sv holds the snippet version. It is sent to the server in the lib.sv block of every event,
making it clear which sites have an outdated snippet.
configure#
rstat4('configure', { /* options */ });
It can be called multiple times: the options are merged. After the library initializes, the call is
ignored with a console warning, so all configuration must be passed before
DOMContentLoaded, i.e. in the snippet.
Main options#
Trackers#
Each tracker is enabled by an object with its settings or by true; false disables it. Keys that are
absent from the object take their default values.
trackActivity#
Measures engagement: it counts the user's DOM events (mouse movement, clicks, keyboard,
touches, scrolling) and once every flushInterval seconds sends an activity event with the counters
for that period. Periods with no actions are not sent, but they are numbered, so iteration and active
show how much time the visitor actually interacted with the page. Separately, the tracker watches
scrolling: when it stops, a scroll event is sent, and a scroll block with the current and maximum
position is added to all user events.
trackActivity: { flushInterval: 10 } // send activity less often
trackActivity: { scrollEvents: false } // no separate scroll events
trackActivity: false // disable entirely
| Key | Default | Description |
|---|---|---|
flushInterval | 5 | Interval for sending the activity event, seconds |
zeroEvents | false | Send activity even without user actions |
scrollEvents | true | Send a scroll event when scrolling has stopped |
domEvents | true | Count DOM events (clicks, keyboard, mouse movement, touches) for activity |
trackClicks#
Intercepts clicks on the page. By default it sends only link_click: from the element under
the cursor it searches upward for the nearest <a>, and the event includes href, the link text, an outbound
flag (points to another host), and a description of the element that was clicked. With allClicks: true, clicks on
any other elements are sent as element_click with the element's tag, class, id, name, and placeholder;
clicks on links still remain link_click. Elements with the ignoreClass class and their descendants are not
tracked, which is a convenient way to exclude, for example, menu toggle buttons or chat widgets.
trackClicks: { allClicks: true, ignoreClass: 'no-track' }
| Key | Default | Description |
|---|---|---|
allClicks | false | false — only link clicks (link_click), true — also clicks on any elements (element_click) |
ignoreClass | 'rst-ignore' | CSS class of elements whose clicks are not tracked |
trackForms#
Tracks interaction with forms and fields: field_focus, field_change, field_blur,
field_invalid at the field level and form_submit at the form level. The event includes the field's attributes
(tag, type, name, placeholder, class, id) and the form's attributes (method, action, name,
class, id), so a completion funnel can be built without marking up the site. Field values are not
collected by default: trackValues: true enables sending them as plain text, and
encryptionKey enables in-browser encryption with a public RSA key, under which the plain text does not
leave the page. If a key is set but WebCrypto is unavailable (for example, the page is not in a secure
context), the value is dropped rather than sent as is.
trackForms: { encryptionKey: 'MIIBIjANBgkq...' } // values are sent encrypted, eenc: 1
trackForms: { trackValues: true } // values as plain text
trackForms: {} // only interaction facts, no values
| Key | Default | Description |
|---|---|---|
trackValues | false | Send field values as plain text in evalue |
encryptionKey | null | Public RSA key (base64 SPKI). If set, field values are encrypted in the browser (WebCrypto RSA-OAEP) and sent with eenc: 1. The plain text does not leave the browser; if encryption is unavailable, the value is dropped |
Encryption requires a secure context: https or localhost. Only a server with the private key can
decrypt the values.
trackRecord#
Session recording: rrweb captures the DOM and all changes on the page, the SDK packs them with fflate and
sends them in rec_batch batches, from which the server reconstructs a video-like recording of the
visitor's actions. rrweb itself is not part of lib.js: a separate rrweb-record.js bundle is loaded from
the tracker server (or from scriptUrl) only when recording starts, so for sites without recording
it adds no weight. By default recording does not start: it is enabled by autostart: true in the configuration
or by a rstat4('record') call at the right moment, for example when entering checkout.
All input fields are masked. For fine-tuning there are three CSS classes: rst-block removes the
element from the recording entirely, rst-mask replaces its text with asterisks, rst-ignore disables recording of input
in a field. A periodic full DOM snapshot (checkoutEveryNms) allows the recording to be replayed from
an arbitrary point.
trackRecord: { autostart: true } // record all sessions from load
trackRecord: { autostart: false, recordCanvas: true } // start via rstat4('record'), with canvas
| Key | Default | Description |
|---|---|---|
autostart | false | true — recording starts on initialization, otherwise only on a rstat4('record') call |
scriptUrl | null | Full URL of the recording bundle if it is not on the tracker server |
maskAllInputs | true | Input field values are not recorded |
blockClass | 'rst-block' | Elements with this class are fully excluded from the recording |
maskTextClass | 'rst-mask' | The element's text is replaced with asterisks |
ignoreClass | 'rst-ignore' | Input events in the element are not recorded |
recordCanvas | false | Record canvas |
checkoutEveryNms | 120000 | Full DOM snapshot interval, ms |
flushInterval | 5 | Buffer flush interval, seconds |
maxBatchBytes | 40000 | Batch chunk size. Together with the message envelope it must fit within the 64 KB beacon limit |
browserEvents#
Page lifecycle. On beforeunload, a page_unload event is sent — the visitor left the
page or closed the tab; on visibilitychange, a page_visibility event with a hidden flag and
the duration of the previous state, from which the real time on the page is computed, accounting for tab
switching and minimizing the browser. Both events are sent via sendBeacon, which
does not block the page and delivers the data on unload. In mobile browsers beforeunload
does not always fire, so for time on page it is more reliable to rely on page_visibility
and activity.
browserEvents: { unloadHandlers: false } // do not send page_unload
| Key | Default | Description |
|---|---|---|
unloadHandlers | true | Send page_unload on beforeunload |
visibilityHandlers | true | Send page_visibility on tab switching |
Full configuration example#
rstat4('configure', {
server: 'stat.example.com',
projectId: 42,
sessionTimeout: 1800,
trackActivity: { flushInterval: 10 },
trackClicks: { allClicks: true, ignoreClass: 'no-track' },
trackForms: { encryptionKey: 'MIIBIjANBgkq...' },
trackRecord: { autostart: false, maskAllInputs: true },
browserEvents: { visibilityHandlers: true }
});
rstat4('page');
Personal overrides#
rstat4('setCustomConfig', config) saves configuration overrides in the browser's storage.
They are applied on subsequent loads on top of the snippet options. This is convenient, for example, to
enable detailed logging or session recording for yourself on a production site without touching the code.
rstat4('setCustomConfig', { trackRecord: { autostart: true } });
Storage#
The SDK uses cookies with the cookiePrefix prefix (rst4-) and localStorage with the lcPrefix prefix
(rst4:). They hold the visitor identifier uid, the current session's data and counters, the last
advertising campaign, userId, and the traits from identify. Cookies are set on cookieDomain with
SameSite=Lax and the Secure flag on https.
The activateWs, wsServer, wsPath, and pixelSync options are reserved and are not used in the
current version.