Documentation
Web-SDK automatic events
All events go to the track service and share a common structure.
Below we describe only the data field of each event and the conditions under which it is generated.
| Event | Source | Enabled by |
|---|---|---|
session | session start or restart | always |
page | rstat4('page') | call |
page_loaded | window.load | always |
page_unload | beforeunload | browserEvents.unloadHandlers |
page_visibility | visibilitychange | browserEvents.visibilityHandlers |
activity | DOM event counter, once per flushInterval | trackActivity |
scroll | scrolling stopped | trackActivity.scrollEvents |
link_click | click on a link | trackClicks |
element_click | click on any element | trackClicks.allClicks |
form_submit | form submission | trackForms |
field_focus, field_blur, field_change, field_invalid | field events | trackForms |
user_params | synchronization with GA4 and Yandex Metrica | always |
rec_start, rec_batch | session recording | trackRecord or rstat4('record') |
Session#
Sent instead of the event that triggered the session start; that event is sent right after.
data is empty, all the information is in the sess block. See more in the
Sessions section.
{
"name": "session",
"data": {},
"sess": {
"pageNum": 0, "eventNum": 0, "num": 1,
"type": "organic", "engine": "google", "refhost": "google.com",
"marks": {}, "hasMarks": false, "start": 1757960000000
}
}
Page view#
The library does not send page on its own; the site calls it. Everything passed into the call
lands in data. A perf block with load timings is added to the event.
{
"name": "page",
"data": { "type": "category", "id": "2342344", "name": "Товары для дома" },
"perf": { "cs": 0, "ce": 0, "scs": -1, "rqs": 211, "rss": 1549, "rse": 1560, "dl": 1581, "di": 1812, "dc": -1 }
}
Page loaded#
Sent on window.load, data is empty, and the perf block is already fully populated.
{ "name": "page_loaded", "data": {}, "perf": { "...": "..." } }
Page unload#
Sent on beforeunload when navigating to another page or closing the tab, data is empty.
Delivered via sendBeacon, so the event makes it out in time.
{ "name": "page_unload", "data": {} }
Tab visibility#
Sent on visibilitychange: the user switched tabs, minimized the browser, or came back.
{
"name": "page_visibility",
"data": {
"hidden": 1, // 1 — tab is hidden, 0 — visible
"state": "hidden", // document.visibilityState
"dur": 48213 // how many ms the previous state lasted
}
}
Activity#
The DOM event counter accumulates statistics and, once every flushInterval seconds (5 by default),
sends them to the server. If there was no activity during the period, the event is not sent, but the
iteration number keeps growing. With zeroEvents: true, empty periods are sent as well.
{
"name": "activity",
"data": {
"interval": 5, // period, seconds
"iteration": 65, // period number since the page loaded
"active": 4, // number of the period with activity
"mousemove": 62,
"mousedown": 2,
"mouseup": 2,
"click": 2,
"wheel": 23,
"scroll": 22,
"keydown": 5,
"touchstart": 1
}
}
The following events are counted: touchmove, touchstart, touchleave, touchenter, touchend,
touchcancel, click, mouseup, mousedown, mousemove, mousewheel, wheel, scroll,
keypress, keydown, keyup, resize, focus, blur. Only those that occurred during the
period land in data. A description of the events is available at
developer.mozilla.org.
Scrolling#
Sent when scrolling has stopped. data is empty, the position is in the scroll block, which
is also added to all other user events.
{ "name": "scroll", "data": {}, "scroll": { "dh": 1148, "ch": 326, "to": 479, "cs": 100, "ms": 100 } }
Link click#
The nearest <a> is searched for upward from the element that received the click. outbound means
the link points to another host. Elements with the trackClicks.ignoreClass class (rst-ignore by default) are not tracked.
{
"name": "link_click",
"data": {
"target": {
"tag": "span", // tag of the deepest element under the cursor
"type": "",
"name": "",
"ph": "", // placeholder
"cls": "menu-item", // class
"id": "",
"href": "",
"text": "Меню"
},
"href": "https://www.example.com/catalog/#menu",
"text": "Текст ссылки",
"outbound": false
}
}
Click on any element#
Only with trackClicks: { allClicks: true }. Clicks on links are still sent as
link_click; element_click is not sent for them.
{
"name": "element_click",
"data": {
"target": {
"tag": "input",
"type": "text",
"name": "city",
"ph": "Введите город прибытия",
"cls": "SearchWidget-input -to",
"id": "",
"href": "",
"text": ""
}
}
}
Form fields#
Four events with the same set of parameters:
field_focus— the caret was placed in the field;field_change— the field value changed;field_blur— the caret left the field;field_invalid— the field failed browser validation on form submission.
Parameters with the e prefix describe the field, those with the f prefix describe the form it belongs to.
{
"name": "field_change",
"data": {
"event": "change", // DOM event
"etag": "input", // element tag
"etype": "text", // type attribute
"ename": "delivery_address", // name attribute
"eph": "", // placeholder
"ecl": "form-field", // class
"eid": "", // id
"evalue": "", // value, see below
"fmthd": "post", // form method
"fact": "/checkout/purchase", // form action
"fname": "order-form", // form name
"fcls": "", // form class
"fid": "order-form" // form id
}
}
If the field is not inside a form, "ferr": "Form element absent" is sent instead of f*.
Field values#
By default, values are not sent, and evalue is empty. The options are:
trackForms: { trackValues: true }— the value is sent as plain text inevalue;trackForms: { encryptionKey: '...' }— the value is encrypted in the browser with a public RSA key (WebCrypto RSA-OAEP) and sent inevaluewitheenc: 1. If encryption is unavailable, the value is dropped andeenc: 0is sent.
Field events are among the most useful for diagnosing problems in forms: the
field_focus → field_change → field_invalid chain shows where the visitor got stuck.
Form submission#
{
"name": "form_submit",
"data": {
"event": "submit",
"fmthd": "post",
"fact": "/cart",
"fname": "cart",
"fcls": "cart-submit",
"fid": "cart-submit"
}
}
Identifier synchronization#
If GA4 or Yandex Metrica is present on the page, the SDK gets their client id and sends the internal
user_params event. The identifiers are saved in storage and are then included in the user block
of every message as ga4ClientId and ymId.
{ "name": "user_params", "data": { "ga4ClientId": "2039255293.1537236640", "ymId": "1537242943246737376" } }
Session recording#
When recording starts, rec_start is sent, then the rrweb buffer is sent in rec_batch batches.
{ "name": "rec_start", "data": { "packed": 1, "masked": 1 } }
{ "name": "rec_batch", "data": { "seq": 3, "part": 1, "of": 2, "p": 1, "d": "[{\"type\":3,..." } }
d is a fragment of a JSON array of packed rrweb events. The array is serialized as a whole and cut into
parts of maxBatchBytes characters each. The server stitches d together by the (uid, lib.st, seq) key
in part order (of is the number of parts), parses the JSON, and unpacks each event (p: 1 — fflate,
p: 0 — raw JSON).
Session recording and identify do not create events with scroll; all other user events
receive a scroll block with the current page position.