Skip to main content

Autocapture

Autocapture lets the browser SDK track what visitors do on your website without a track() call for every action. It records page views and page leaves, and can also record clicks and form submits. Every event carries the page, session and campaign it belongs to.

The Web Analytics dashboard is built from these events.

Autocapture is opt-in. Nothing is captured until you turn it on, and clicks and form submits are a separate opt-in on top of page views.

Requirements
  • Page views and page leaves need @dashx/browser 0.13.1 or later.
  • Clicks and form submits need @dashx/browser 0.14.1 or later.
  • With React, the autocapture prop needs @dashx/react 0.5.0 or later, and 0.5.2 or later for clicks and form submits.

Turn it on​

import DashX from '@dashx/browser'

DashX.configure({
publicKey: '...',
targetEnvironment: '...',
autocapture: true,
})

You can also start and stop it at runtime:

DashX.startAutocapture()
DashX.stopAutocapture()

Calling startAutocapture() again replaces the running capture with the new options. Calling DashX.configure() again stops the previous client's autocapture. On the server (during server-side rendering) there is no page to observe, so startAutocapture() does nothing.

Choose what to capture​

autocapture: true captures page views and page leaves. Pass an object instead to choose:

OptionDefaultCaptures
pageviewstrue$pageview events
pageleavetrue$pageleave events
clicksfalse$autocapture events for clicks and form submits
DashX.configure({
// ... other configuration options

// Page views and page leaves
autocapture: true,

// Page views, page leaves, clicks and form submits
// autocapture: { clicks: true },

// Page views only
// autocapture: { pageleave: false },
})

Events​

Up to three events are captured:

EventWhenData
$pageviewOn load and on every client-side navigation (pushState, replaceState, back and forward, and #/ hash-router routes)url, path, referrer, title
$pageleaveWhen the visitor navigates to another page, or the tab is hidden or closedurl, path, referrer, title, durationMs
$autocaptureOnly with clicks: true: on a click on a link, button or other interactive element, and on a form submiteventType (click or submit), tagName, text, href, elementId, name, role, type, ariaLabel, classes, dataAttributes, selector, path

A change to only the query string or an in-page anchor is not a new page. A page view is recorded 300ms after the navigation, so title is the new route's title and not the previous page's.

note

These event names start with $ and are used by DashX. Use your own names, such as Button Clicked, for events you track yourself with track().

Clicks and form submits​

Turn clicks on with autocapture: { clicks: true }.

A click is credited to the nearest interactive element around what was clicked: a link with an href, a button, a summary, a button-like input, a checkbox, a radio, or an element with an interactive role such as button, link, tab or menuitem. Clicks on anything else are ignored. To record clicks on an element that is not otherwise interactive, add the data-dx-capture attribute to it:

<div data-dx-capture>Open details</div>

A recorded click looks like this:

{
"eventType": "click",
"tagName": "button",
"text": "Start free trial",
"classes": ["btn", "btn-primary"],
"selector": "section.hero > div.cta > button#trial.btn.btn-primary",
"path": "/pricing"
}
FieldMeaning
eventTypeclick or submit.
tagNameThe element's tag, in lower case.
textThe element's visible text, up to 255 characters. Icon-only elements have none.
hrefThe link target, for links. javascript: links are left out.
elementIdThe element's id.
name, role, typeThe element's name, role and type attributes.
ariaLabelThe element's aria-label, or its title when it has no aria-label. This names icon-only elements.
classesUp to five of the element's CSS classes.
dataAttributesThe element's data-* attributes that have a value.
selectorThe element and up to four of its ancestors, outermost first. It tells apart elements that have the same text.
pathThe path of the page the event happened on.

A form submit is recorded with the form's tag, id, name, classes, data-* attributes and selector. It does not carry the form's fields. Because a submit button is itself clickable, submitting a form with its button can be recorded as both a click and a submit.

Skip an element​

Add the dx-no-capture class or the data-dx-no-capture attribute to an element to skip it and everything inside it:

<div class="dx-no-capture">
<button>Reveal account number</button>
</div>

What is never captured​

  • What was typed. An input contributes its value only when it is a button's label. Text typed into fields is never recorded.
  • Card and social security numbers. Any recorded text that looks like a card number or a US social security number is dropped, whether it is visible text, a button's value, aria-label, title, name or a data-* value.
warning

The visible text of a clicked element is recorded. If an element shows personal data, for example a customer's name in a list row that can be clicked, add dx-no-capture to it or to a container around it. You can also drop or edit events with beforeSend.

Sessions and campaigns​

Every event sent from the browser, whether autocaptured or sent with track(), carries the page it happened on and a session id.

  • A session ends after 30 minutes without a tracked event, and when you call DashX.reset(). It is shared across the tabs of the same site.
  • If the landing URL has utm_source, utm_medium, utm_campaign, utm_term or utm_content, they are attached to every event in that session as its campaign. This includes events after client-side navigation has dropped them from the URL.

Custom events​

Events you send with DashX.track() in the browser carry the same page, session and campaign, so they line up with autocaptured events:

DashX.track('Plan Selected', { plan: 'pro' })

track() sends the event right away, together with any autocaptured events that are still queued. It resolves once the event is sent, and it never rejects: a failed send is logged. While autocapture is running, track() reports the current URL with the referrer that autocapture recorded.

Privacy controls​

URLs and referrers are sent in full, including the query string. To keep personal data out of them, and to filter events before they are sent:

DashX.configure({
// ... other configuration options

autocapture: true,

// Replaces ad-click ids (gclid, fbclid, msclkid and similar) with `<masked>`.
maskPersonalDataProperties: true,

// Masks these query parameters too. Only applies with maskPersonalDataProperties.
customPersonalDataProperties: ['token', 'email'],

// Runs on every event before it is sent.
// Return the event, edited as needed, or null to drop it.
beforeSend: (event) => {
if (event.event === '$pageleave') return null
return event
},
})
  • Masking applies to captured URLs and referrers, and to the href of clicked links.
  • beforeSend also accepts an array of functions, which run in order. The first one to return null drops the event, and a function that throws drops it too.
  • beforeSend applies to events from track() as well as autocaptured ones.

How events are sent​

Autocaptured events are sent in batches, every 5 seconds or every 20 events. When the page is hidden, the last batch is sent with fetch and keepalive so it survives the page being closed. Browsers limit the total size of keepalive requests that are in flight to 64KB, so a request that would go over the limit is sent without keepalive instead of failing.