Browse docs

The install snippet

How the loader stub and the asynchronous command queue work under the hood.

The install snippet is the only piece of code you ever paste into your site. It is a tiny loader stub that bootstraps NudgeVisor in a handful of bytes, then pulls in the full widget asynchronously so it never blocks your page. This article explains exactly what the snippet does, line by line, so you understand what is running on your pages and why it is safe to start calling the API immediately. If you just want copy-and-paste instructions, see Installing the widget.

The snippet

This is the complete snippet, with your site's public key in place of YOUR_PUBLIC_KEY. In the dashboard the key is already filled in for you and a one-click copy button is provided.

<script>
(function(w,d,k){
  w.NudgeVisor=w.NudgeVisor||{q:[]};
  ['identify','setAttributes','on'].forEach(function(m){
    w.NudgeVisor[m]=w.NudgeVisor[m]||function(){w.NudgeVisor.q.push([m,[].slice.call(arguments)])};
  });
  w.NudgeVisor.publicKey=k;
  var s=d.createElement('script');s.async=1;
  s.src='https://app.nudgevisor.com/widget/v1.js';
  s.setAttribute('data-nv-key',k);
  d.head.appendChild(s);
})(window,document,'YOUR_PUBLIC_KEY');
</script>

The whole thing is an immediately-invoked function expression (IIFE). It is passed window as w, document as d and your public key as k, then executes synchronously the moment the browser parses it.

Anatomy of the loader stub

The stub does three small things, in order.

1. Create the global object and command queue

It creates window.NudgeVisor (if it does not already exist) with a command queue, q: []. The queue is where every early API call is parked until the real widget is ready to handle it.

2. Define the stub methods

It defines stub versions of identify, setAttributes and on. Each stub does nothing more than push [method, args] onto the queue. Because the real implementations do not exist yet, these placeholders give you a stable API surface to call against from the very first moment.

// Defines the global object and its command queue
window.NudgeVisor = window.NudgeVisor || { q: [] };

// Each public method is a thin stub that records the call
window.NudgeVisor.identify = function () {
  window.NudgeVisor.q.push(['identify', [].slice.call(arguments)]);
};

3. Set the key and inject the real widget

Finally it stores your publicKey on the global object, then creates a <script> element pointing at https://app.nudgevisor.com/widget/v1.js. The script is marked async (s.async=1) and carries your key in a data-nv-key attribute before being appended to the document head. The public key tells NudgeVisor which site the captured data belongs to — see API keys for how to find and rotate it.

Why the command queue matters

Because the stubs simply queue calls, you can safely invoke NudgeVisor.identify(...), setAttributes(...) or on(...) immediately after the snippet — even before the full widget has finished downloading. Nothing is lost.

<script>
  // ... the loader snippet has just run above ...
  // This is safe even though /widget/v1.js may still be downloading.
  NudgeVisor.identify('user-42', { email: '[email protected]' });
  NudgeVisor.setAttributes({ plan: 'pro' });
</script>

When /widget/v1.js finishes loading it drains the queue: it walks through every entry you pushed and replays each one against the real implementation, in the original order. From your point of view the API is available the instant the snippet runs; the queue absorbs the timing difference for you. This is why you never need to wrap calls in a setTimeout or a load listener.

What the full widget does once loaded

After the asynchronous script arrives and drains the queue, the real widget takes over and:

  • patches history.pushState and history.replaceState so single-page-app navigation is tracked as distinct page views;
  • sends a heartbeat beacon on a recurring interval and on every visibilitychange, keeping the live visitor view current;
  • initialises chat, exposing openChat alongside the queued methods;
  • starts the session recorder so the visit can be replayed later.

From this point the methods available to you are identify, setAttributes, and on plus openChat — both covered under widget events.

Where to put it

Place the snippet just before the closing </head> tag on every page you want to track. Because the widget script is loaded with async, the snippet never blocks rendering — but putting it in the <head> means capture begins as early as possible, so you do not miss the opening moments of a session. If your site shares a layout or template, add it there once to cover the whole site.

Related

  • API keys — find, scope and rotate the public key the snippet uses.
  • Identify — attach a real identity to the current visitor.
  • Widget events — listen with on and open chat with openChat.