> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.pivolio.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.pivolio.com/_mcp/server.

# Script tag

The IIFE build of [`@pivolio/browser`](/documentation/sd-ks/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

```html
<script>
  window.pivolio = window.pivolio || [];
  pivolio.push(['init', {
    writeKey: 'wk_live_xxxxxxxxxxxx',
    apiUrl: 'https://api.pivolio.com',
  }]);
  pivolio.push(['page']);
</script>
<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

> **Warning**
>
> **`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:

```html
<script>
  window.pivolio = window.pivolio || [];
  pivolio.push(['init', {
    writeKey: 'wk_live_xxxxxxxxxxxx',
    apiUrl: 'https://api.pivolio.com',
  }]);
  pivolio.push(['identify', { user_id: 'user_456', email: 'jane@acme.com' }]);
  pivolio.push(['track', 'order_completed', {
    properties: { order_id: 'ord_123', revenue: 99.5, currency: 'USD' },
  }]);
</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 queue                                            | Not replayable                                 |
| -------------------------------------------------------------------- | ---------------------------------------------- |
| `init`, `page`, `track`                                              | `flush`                                        |
| `trackPurchase`, `trackAddToCart`, `trackBeginCheckout`, `trackLead` | `destroy`                                      |
| `identify`, `setConsent`, `reset`                                    | `getAnonymousId`, `getSessionId`, `getUserId`  |
| `optOut`, `optIn`, `debug`                                           | `getLinkerParam`, `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.

> **Note**
>
> `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](/documentation/sd-ks/browser#reset-and-destroy).

## Direct global usage

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

```html
<script>
  Pivolio.init({
    writeKey: 'wk_live_xxxxxxxxxxxx',
    apiUrl: 'https://api.pivolio.com',
  });

  Pivolio.page();
  Pivolio.trackPurchase({ value: 99.5, currency: 'USD', orderId: 'ord_123' });

  console.log(Pivolio.getAnonymousId());
</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:

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

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

> **Note**
>
> 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

* [Browser SDK](/documentation/sd-ks/browser) — the full method surface.
* [Configuration](/documentation/sd-ks/configuration) — every option you can pass to `init`.
* [First-party domains](/documentation/guides/first-party-domains) — serve the collector
  from your own subdomain to beat ad-blockers.