Script tag

Install from a CDN, with an async command queue and no build step.

The IIFE build of @pivolio/browser exposes a global named Pivolio and drains any commands you queued before it finished loading. Use it on a CMS, a landing page builder, or anywhere you can’t run a bundler.

Install

1<script>
2 window.pivolio = window.pivolio || [];
3 pivolio.push(['init', {
4 writeKey: 'wk_live_xxxxxxxxxxxx',
5 apiUrl: 'https://api.pivolio.com',
6 }]);
7 pivolio.push(['page']);
8</script>
9<script async src="https://unpkg.com/@pivolio/browser@1/dist/browser.browser.js"></script>

The @1 in the URL pins the major version, so you get patches and features without a breaking change landing unannounced.

Two names, two different things

Pivolio (capital P) is the API object, available only after the script has loaded. window.pivolio (lowercase) is the command queue — a plain array. Calling pivolio.track(...) will throw, because an array has no track method.

  • window.pivolio — an array you push() command tuples onto. Safe to use before the script loads. This is the whole point of the queue: you can record a purchase on a page where the script is still in flight and it will replay.
  • Pivolio — the real API, with every export as a method. Only safe after the script has loaded.

The async queue

Push a tuple of [method, ...args]. On load, the bundle walks the queue in order and replays each command:

1<script>
2 window.pivolio = window.pivolio || [];
3 pivolio.push(['init', {
4 writeKey: 'wk_live_xxxxxxxxxxxx',
5 apiUrl: 'https://api.pivolio.com',
6 }]);
7 pivolio.push(['identify', { user_id: 'user_456', email: 'jane@acme.com' }]);
8 pivolio.push(['track', 'order_completed', {
9 properties: { order_id: 'ord_123', revenue: 99.5, currency: 'USD' },
10 }]);
11</script>

Note that track takes its arguments as separate queue elements — ['track', name, data] — and that properties stay nested under properties, exactly as in the module API.

What replays, and what doesn’t

Replayable from the queueNot replayable
init, page, trackflush
trackPurchase, trackAddToCart, trackBeginCheckout, trackLeaddestroy
identify, setConsent, resetgetAnonymousId, getSessionId, getUserId
optOut, optIn, debuggetLinkerParam, hasOptedOut, getInstance

The pattern is straightforward: the queue replays commands, not queries. A getter pushed onto the queue has nowhere to return its value to, so it is silently ignored — no error, no console warning. Everything in the right-hand column works fine on the Pivolio global once loaded.

reset is replayable, but remember it also destroys the singleton. If you push ['reset'] you must push another ['init', config] after it, or nothing will track. See the browser SDK warning.

Direct global usage

Once the script has loaded, skip the queue and call the global:

1<script>
2 Pivolio.init({
3 writeKey: 'wk_live_xxxxxxxxxxxx',
4 apiUrl: 'https://api.pivolio.com',
5 });
6
7 Pivolio.page();
8 Pivolio.trackPurchase({ value: 99.5, currency: 'USD', orderId: 'ord_123' });
9
10 console.log(Pivolio.getAnonymousId());
11</script>

To do this safely from a page that loads the bundle with async, hook the script’s load event rather than guessing at the timing:

1<script
2 async
3 src="https://unpkg.com/@pivolio/browser@1/dist/browser.browser.js"
4 onload="Pivolio.debug(true)"
5></script>

The two styles mix freely. Queue what you can before load, then use the global for getters and for flush().

The IIFE bundle also exposes the Tracker class and the StandardEventName, ConsentStatus and DeviceType enums. It does not expose the version export — if you need the version at runtime, use the npm package.

Next steps