Docs menu · Script reference

Docs › Developers

Script reference

The tracking script's attributes, its JavaScript API, the queue for early calls, and everything it does on its own.

The script tag

<script defer src="https://nviv.io/js/NV-XXXXXXX.js"></script>

Each site gets its own build with the site code in it, and only the code it needs: a site in privacy mode gets no cookie code, and options you turned off in What the script measures are left out. Changes reach your visitors within ten minutes.

  • Size: smaller than 1 kB gzip. Every build is measured and refused above 1,024 bytes (minus a 6-byte margin).
  • Loading: with defer, it never holds up your page.
  • Sending: events go out with sendBeacon, so they also leave when a page closes.
  • Content-Security-Policy: there is no inline code. Allow https://nviv.io in script-src and connect-src.

The older, generic form still works but does not follow the per-site options:

<script defer src="https://nviv.io/s.js" data-site="NV-XXXXXXX"></script>

Attributes

Attribute What it does
data-site The site code. Only for the generic s.js; the per-site script already has it.
data-api Send events to another address than nviv.io, for example a proxy on your own domain: data-api="/stats/e".
data-consent="none" In cookie mode: set the cookie right away, without waiting for nvivio.consent(). Only use this where you do not need consent.

JavaScript API

// Count an action, with up to 20 properties.
window.nvivio?.track('signup', { plan: 'pro' });

// Cookie mode: the visitor gave consent, so set the first-party cookie now.
window.nvivio?.consent();
  • Event names: letters, digits, spaces, dot, colon, hyphen or underscore, up to 64 characters.
  • Properties: up to 20 per event; names up to 40 characters, text up to 200 characters.
  • Without code: data-event="signup" on an element, with data-event-plan="pro" for a property. See Events.

Early calls

If your site calls nvivio.track() or nvivio.consent() before the script has loaded (for example inline in the <head>), add this line just above the script tag:

<script>window.nvivio=window.nvivio||{q:[],track:function(n,p){this.q.push([n,p])},consent:function(){this.c=1}}</script>

The calls wait and are sent once the script runs, consent first. Pageviews, clicks, downloads and data-event buttons do not need it. The installation page shows this line under “Advanced”; API: early_calls in GET /v1/sites/{site}/install.

What the script does on its own

  • Pageviews, including navigation without a reload (see below).
  • Outbound links and downloads, with the link text (up to 80 characters), unless turned off. Files: pdf, zip, doc, docx, xls, xlsx, ppt, pptx, csv, dmg, exe, mp3 and mp4. They arrive as the events outbound and download.
  • Time on page and scroll depth, in steps of 25%, sent when the visitor leaves the page or hides the tab.
  • Counts once, even when the script is on the page twice: the first copy counts and the others stop.
  • Prerendered pages (that Chrome prepares in the background) only count when the visitor actually opens them.

Single-page apps and hash routes

Navigation through history.pushState, back and forward counts as a pageview by itself, in React, Vue, Svelte and other single-page apps. A jump to #section on the same page does not count as a new page.

Sites that switch pages with #/page can count those routes as pages: Settings › What the script measures › Hash routes as separate pages. The route is then stored as a path, for example /#/pricing.

The site code

Every site has a neutral code such as NV-9Y5FVJQ: six characters from an alphabet without I, L, O and U, plus a check character that catches any typo of one character. Lowercase and the usual swaps (O for 0, I or L for 1) are accepted.

Errors from the endpoint

Every error from the endpoint that receives events has an error and a fix: what is wrong and how to solve it, for example an unknown site code or a domain that does not belong to the site (“Add the domain in the site settings”). Events from domains that are not in your site’s domains, including localhost, are refused.