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.ioinscript-srcandconnect-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, withdata-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
outboundanddownload. - 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.