> 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.

# Shopify SDK

`@pivolio/shopify` runs inside a [Shopify Web Pixel](https://shopify.dev/docs/api/web-pixels-api)
extension. It subscribes to the storefront's standard customer events, maps them
to Pivolio event names, and posts them to the collector.

> **Note**
>
> Most merchants don't need this package. Installing the **Pivolio app** from the
> Shopify admin covers both the storefront funnel and the authoritative
> server-side purchase — see [Shopify integration](/documentation/integrations/shopify).
> Reach for `@pivolio/shopify` only when you're building your own app pixel or
> custom pixel.

## Install

```bash
npm install @pivolio/shopify
```

Zero runtime dependencies — `@pivolio/core` is bundled in. Ships ESM, CommonJS
and types. The package is sandbox-native: it has no DOM access and reads
everything through the Web Pixel API.

## Usage

Call `createShopifyPixel` from your extension's `register` callback. `writeKey`
and `apiUrl` come from the pixel's settings, configured when the pixel is created
via `webPixelCreate`:

```ts
import { register } from '@shopify/web-pixels-extension';
import { createShopifyPixel } from '@pivolio/shopify';

register((api) => {
  void createShopifyPixel(api);
});
```

It resolves the per-visit context once, then forwards every mapped event to
`${apiUrl}/track`. If `writeKey` or `apiUrl` is missing from settings it no-ops
rather than throwing.

> **Note**
>
> The pixel posts to `/track`, so either a first-party SDK write key or a Shopify
> integration key works. Prefer the integration key created under
> **Integrations → Shopify** — it keeps store traffic attributable to that source
> and lets you rotate it without touching your site's own key.
>
> The 403 that rejects SDK keys applies only to `/ingest/integration`, which this
> pixel does not use.

## Event mapping

The pixel subscribes to `all_standard_events` and forwards the six below.
Anything else is dropped.

| Shopify event            | Pivolio event      | Captured properties                       |
| ------------------------ | ------------------ | ----------------------------------------- |
| `page_viewed`            | `page_view`        | —                                         |
| `product_viewed`         | `view_content`     | `value`, `currency`, `product_id`         |
| `search_submitted`       | `search`           | `query`                                   |
| `product_added_to_cart`  | `add_to_cart`      | `value`, `currency`, `product_id`         |
| `checkout_started`       | `begin_checkout`   | `value`, `currency`, + email/phone traits |
| `payment_info_submitted` | `add_payment_info` | `value`, `currency`                       |

`checkout_completed` is **deliberately not forwarded**. The purchase conversion
is owned by the server-side `orders/paid` webhook in the Pivolio Shopify
integration, which is authoritative and immune to ad-blockers. Emitting it from
the pixel as well would double-count every order.

## Identity and attribution

The pixel resolves a durable anonymous id into the first-party `_at_aid` cookie,
with a one-year lifetime, so a visitor keeps one id across visits. It also
captures UTM parameters, ad-platform click IDs (`gclid`, `fbclid`, `ttclid`, …)
and the first-party pixel cookies `_fbp`, `_fbc` and `_ttp` — the last three
being a meaningful lift in Meta and TikTok match rates.

## Exports

| Export                        | Description                                                            |
| ----------------------------- | ---------------------------------------------------------------------- |
| `createShopifyPixel(api)`     | Wire a Web Pixel to Pivolio                                            |
| `mapShopifyEvent(name, data)` | Pure mapper: Shopify event → Pivolio event + track data, or `null`     |
| `resolveSnapshot(api)`        | Resolve per-visit context (anonymous id, campaign, click IDs, session) |
| `SandboxContextProvider`      | `ContextProvider` backed by a resolved snapshot                        |
| `SHOPIFY_LIBRARY_NAME`        | The `library.name` stamped on every emitted event                      |

Types for the Web Pixel API surface and Shopify event data are exported
alongside. `mapShopifyEvent` is pure and side-effect free, which makes it the
useful seam if you want to test or extend the mapping in your own extension.

## Next steps

* [Shopify integration](/documentation/integrations/shopify) — the managed app, and the
  `orders/paid` webhook that owns purchases.
* [Events](/documentation/core-concepts/events) — what each standard event name means for
  attribution.