Integration
Tracker script
One file, about 11 KB gzipped, covering analytics, funnels, heatmaps and automations.
The tag
<script
defer
data-website-id="YOUR_WEBSITE_ID"
src="https://app.seentics.com/trackers/seentics.min.js"
></script>defer matters: the tracker reads its own <script> element to find its configuration, so it needs the tag to exist in the document.
Script attributes
Four attributes, and only the first is required. Anything not listed here is ignored — the tracker reads exactly these.
| Attribute | Default | What it does |
|---|---|---|
data-website-id | required | The website UUID from Settings → Tracking. Without it the tracker logs a console error and sends nothing. |
data-api-host | the script's own origin | Where events are sent. Derived from the src origin when omitted, so a self-hosted install usually needs nothing. Set it when your API lives on a different host. A trailing /api/v1 is stripped, so either form works. |
data-auto-track | true | Set to "false" to stop automatic pageviews and send them yourself with seentics.page(). |
data-rrweb-src | seentics-dom.min.js beside the tracker | Where to load the session recorder from. Only needed if you serve the two files from different places. |
data-capture-console | on | Set to "off" to leave console untouched. On, recordings include console output (scrubbed for credentials); off, the override is never installed. |
data-capture-network | on | Set to "off" to leave fetch and XMLHttpRequest untouched. On, recordings include request method, URL, status and duration — never bodies. |
Two attributes that used to be documented do not exist
data-debug and data-mask-pii appeared in earlier versions of these docs and were never read by the tracker. There is no masking attribute because masking is not optional — see below.Browser API
The tracker exposes four methods on window.seentics. They are safe to call as soon as the script has run.
| Method | What it does |
|---|---|
seentics.track(name, props?) | Records a custom event. Also evaluates any funnel step matching that event name, and fires automations with a Custom Event trigger — one call, three effects. |
seentics.identify(userId, traits?) | Attaches your own user ID to this visitor. Stored against their profile, so it survives reloads and later sessions, and fires automations with an Identify trigger. The anonymous visitor ID is left as it is, so calling this does not split one person into two visitors in your reports. |
seentics.page() | Sends a pageview manually. Useful when you have set data-auto-track="false". |
seentics.flush() | Sends anything still queued immediately, rather than waiting for the next batch. |
// A custom event with properties.
seentics.track('add_to_cart', {
sku: 'TRAILHEAD-32L',
value: 168,
});
// Tie this visitor to your own user record.
seentics.identify('user_8412', { plan: 'growth' });
// Manual pageview, for data-auto-track="false".
seentics.page();Single-page apps
Nothing to wire up. The tracker hooks pushState, replaceState and popstate, so a client-side route change is recorded as a pageview on its own. React Router, Next.js and Vue Router all work with the plain tag.
If you would rather control it yourself, set data-auto-track="false" and call seentics.page() from your router.
What it costs the page
| File | Gzipped | When it loads |
|---|---|---|
seentics.min.js | ~11 KB | Always. Analytics, funnels, heatmaps and automations are all in here. |
seentics-dom.min.js | ~56 KB | On demand — only when session recording is enabled for the site and this visitor is sampled in. |
If recording is off, the recorder is never fetched. If it is on but a visitor is not sampled, it is still never fetched for them.
Storage and cookies
The tracker sets no cookies — it never touches document.cookie. It does use browser storage: a visitor ID in localStorage so returning visitors are recognised, and sessionStorage for per-tab session state such as funnel progress.
Worth knowing for your consent notice
localStorage is generally treated the same as a cookie under ePrivacy and the GDPR, even though it is not one. “No cookies” is accurate; “nothing to consent to” is a legal question for your own counsel. See Privacy & security for what is stored.When a site uses Strict consent mode, the tracker stays off until consent is granted. Set data-consent="granted" on the script tag after your consent manager has approval, or set window.seenticsConsent = true before loading the tracker. The tracker also honors browser Do-Not-Track when that setting is enabled for the site.
Excluding elements from recordings
Every input is masked in recordings, always. It is not a setting — maskAllInputs is fixed on in the recorder's configuration, so typed values never leave the browser.
For anything else you do not want captured, mark the element. Both attributes are read straight from the DOM by the recorder, so they work on any element at any time.
| Attribute | Effect |
|---|---|
data-seentics-block | The element is replaced by a placeholder of the same size in the recording. Its contents are never captured. Use this for anything genuinely sensitive. |
data-seentics-mask | The element still renders and animates in the recording, but its text is replaced with asterisks. Use it where the layout matters and the words do not. Rich-text editors (contenteditable) are masked this way already, without the attribute. |
data-seentics-ignore | The element is recorded, but changes inside it are not tracked. Use this for noisy widgets — tickers, clocks, live counters. |
<!-- Never captured. -->
<div data-seentics-block>
<p>Card ending 4242 · Balance $1,204.55</p>
</div>
<!-- Shape kept, words replaced with asterisks. -->
<p data-seentics-mask>Hi Dana, your order ships Tuesday.</p>
<!-- Captured once, then left alone. -->
<div data-seentics-ignore>
<span id="live-clock">14:22:07</span>
</div>