Documentation

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#

  1. Creates the global rstat4 function with a _q queue. Inserting the snippet again is safe: if window.rstat4 already exists, the loader does nothing.
  2. Every rstat4(...) call made before the library loads is pushed onto the queue and returns 0.
  3. Calling rstat4('configure', { server }) kicks off the asynchronous load of https://<server><pathPrefix>/lib.js.
  4. 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#

ParameterData typeDefaultDescription
serverStringnullRequired. Tracker server domain without scheme or path. Example: stat.example.com. lib.js is loaded from it and events are sent to it
pathPrefixString''Path prefix on the server. lib.js and events are requested at URLs like <pathPrefix>/lib.js, <pathPrefix>/band/t4k.json
urlMarkString'band'Path segment for event delivery: /<urlMark>/t4k.json
projectIdNumberdomain hashProject identifier. If not set, it is computed from the page domain, see buildProjectId
allowHTTPBooleanfalseAllow working on http pages. By default the SDK only works over https
allowSendBeaconBooleantrueSend events via navigator.sendBeacon
allowXHRBooleantrueAllow sending via fetch
sessionTimeoutNumber1800Session timeout in seconds: how long without events before a new session starts
lastCampaignExpiresNumber7776000How long the last ad campaign is kept, in seconds (90 days)
initialUidNumber0Initial visitor uid, if it must be set from outside
cookieDomainStringpage domainDomain the cookies are set on
cookiePathString'/'Cookie path
cookiePrefixString'rst4-'Prefix for the names of all cookies the SDK sets
lcPrefixString'rst4:'Prefix for keys in localStorage
trackActivityBoolean, Object{ zeroEvents: false, scrollEvents: true, domEvents: true }Activity and scrolling: the activity and scroll events. Settings in the "Trackers" section
trackClicksBoolean, Object{ allClicks: false }Clicks: link_click and, with allClicks, element_click
trackFormsBoolean, Object{}Forms and fields: form_submit, field_focus, field_blur, field_change, field_invalid
trackPagesBooleanfalseReserved. Automatic URL-change tracking in SPAs is not implemented yet, call page manually
trackRecordBoolean, Object{ autostart: false }Session recording (rrweb)
browserEventsBoolean, Object{ unloadHandlers: true, visibilityHandlers: true }The page_unload and page_visibility events
activateWs, wsServer, wsPathBoolean, String, Stringfalse, null, '/wss'WebSocket transport. Reserved, not used in the current version
pixelSyncBoolean, ObjectfalsePixel interception. Reserved, not used in the current version

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
KeyDefaultDescription
flushInterval5Interval for sending the activity event, seconds
zeroEventsfalseSend activity even without user actions
scrollEventstrueSend a scroll event when scrolling has stopped
domEventstrueCount 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' }
KeyDefaultDescription
allClicksfalsefalse — 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
KeyDefaultDescription
trackValuesfalseSend field values as plain text in evalue
encryptionKeynullPublic 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
KeyDefaultDescription
autostartfalsetrue — recording starts on initialization, otherwise only on a rstat4('record') call
scriptUrlnullFull URL of the recording bundle if it is not on the tracker server
maskAllInputstrueInput 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
recordCanvasfalseRecord canvas
checkoutEveryNms120000Full DOM snapshot interval, ms
flushInterval5Buffer flush interval, seconds
maxBatchBytes40000Batch 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
KeyDefaultDescription
unloadHandlerstrueSend page_unload on beforeunload
visibilityHandlerstrueSend 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.