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.
- Page views and page leaves need
@dashx/browser0.13.1 or later. - Clicks and form submits need
@dashx/browser0.14.1 or later. - With React, the
autocaptureprop needs@dashx/react0.5.0 or later, and 0.5.2 or later for clicks and form submits.
Turn it on
- JavaScript
- React
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.
import { DashXProvider } from '@dashx/react'
<DashXProvider
publicKey="..."
targetEnvironment="..."
autocapture={true}
>
<App />
</DashXProvider>
The provider starts autocapture when it mounts and stops it when it unmounts. Changing the autocapture value restarts it.
Choose what to capture
autocapture: true captures page views and page leaves. Pass an object instead to choose:
| Option | Default | Captures |
|---|---|---|
pageviews | true | $pageview events |
pageleave | true | $pageleave events |
clicks | false | $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:
| Event | When | Data |
|---|---|---|
$pageview | On load and on every client-side navigation (pushState, replaceState, back and forward, and #/ hash-router routes) | url, path, referrer, title |
$pageleave | When the visitor navigates to another page, or the tab is hidden or closed | url, path, referrer, title, durationMs |
$autocapture | Only with clicks: true: on a click on a link, button or other interactive element, and on a form submit | eventType (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.
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"
}
| Field | Meaning |
|---|---|
eventType | click or submit. |
tagName | The element's tag, in lower case. |
text | The element's visible text, up to 255 characters. Icon-only elements have none. |
href | The link target, for links. javascript: links are left out. |
elementId | The element's id. |
name, role, type | The element's name, role and type attributes. |
ariaLabel | The element's aria-label, or its title when it has no aria-label. This names icon-only elements. |
classes | Up to five of the element's CSS classes. |
dataAttributes | The element's data-* attributes that have a value. |
selector | The element and up to four of its ancestors, outermost first. It tells apart elements that have the same text. |
path | The 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,nameor adata-*value.
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_termorutm_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
hrefof clicked links. beforeSendalso accepts an array of functions, which run in order. The first one to returnnulldrops the event, and a function that throws drops it too.beforeSendapplies to events fromtrack()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.