Web Pixel Extensions
Web Pixels listen for customer-events (page_viewed, product_viewed,
product_added_to_cart, checkout_started, checkout_completed). They
are how analytics and marketing apps observe customer behavior without
direct DOM access to the store theme.
Runtime sandbox
Pixels run in a sandboxed runtime with no access to the host page — depending on where they run:- Storefront — the pixel runs in a dedicated Web Worker (created
from a Blob via
new Worker(url)). A Worker has no DOM, no cookies and nodocumentat all; the pixel script is loaded withimportScripts. - React checkout / cart / account — the pixel runs in an
srcdociframe loaded withsandbox="allow-scripts"(noallow-same-origin).
- Read or write cookies on the parent page.
- Read or write
localStorage/sessionStorageon the parent. - Make same-origin requests against the store.
- Read the parent DOM.
postMessage from the host to the pixel runtime —
your pixel subscribes to a stable event API documented below.
Manifest
Declare Web Pixels underextensions.webPixels[] in your app’s
app.json (same manifest file as every other extension type):
*One of
scriptSrc or inlineScript is required.
Pixel runtime API
The sandbox exposes two globals:register and analytics. Both work
identically on both runtimes (storefront Worker and checkout iframe).
register(callback) — recommended
register hands your callback an object with the event bus and the
merchant’s saved settings for this pixel:
Semantics:
- The callback runs synchronously, before the host delivers any event — subscriptions made inside it never miss an event.
- If the callback throws, the error is caught and the sandbox keeps
running. On the iframe runtime the host also receives an
LMS_PIXEL_ERRORmessage withreason: 'register-callback-threw'. - Calling
registerwith a non-function is a safe no-op. - Calling
registermore than once is allowed; each callback runs once.
analytics.subscribe(eventName, cb) — top level
Subscribing at the top level of your script also works, and remains fully
supported. It has no access to configuration:
settings/init argument
and no browser proxy — the sandbox is a Web Worker (storefront) or a
same-origin-blocked iframe (checkout), so no host-page storage exists.
Event catalogue
Payloads use the stable customer-event shapes documented above, so a
pixel can subscribe to event names and read the listed payload fields
without further translation.
Installation
The pixel JS + manifest are deployed by the install pipeline (POST /api/apps/install-extensions), a server-to-server endpoint
gated by the platform’s internal API key — it is not called directly from
the browser with a merchant token (the only browser-accepted path is a
fromCatalog: true catalog copy). The storefront’s pixel loader picks the
pixel up on the next page load.
Uninstall removes the pixel directory and the storefront stops sending
events to it on the next render.
Best practices
- Prefer
register. It is the only way to read the merchant’ssettingsfrom inside the sandbox. Reach for top-levelanalytics.subscribeonly when your pixel needs no configuration. - Don’t bake merchant config into
scriptSrc. One script is served to every store that installs your app; per-store values belong insettingsand arrive asconfiguration. - Use
navigator.sendBeaconoverfetch. The pixel runtime may be torn down during navigation —sendBeaconsurvives. - Don’t expect cookies to persist between visits. The pixel runs in a Worker (storefront) or a sandboxed iframe (checkout) with no host-page storage.