Events & analytics glue
Every wishlist interaction emits a DOM event — forward them to your analytics stack in a few lines.
This page lists every event the components emit and shows how to wire them into GA4, a data layer, or any tracker.
The events
All events bubble and cross shadow-DOM boundaries (composed), so one listener on document
catches everything. Payloads are on event.detail.
| Event | Fired by | detail |
|---|---|---|
envie:ready | the store, on document | { count, config, list } — first load complete, once per page |
envie:added | envie-button | { productId, variantId, handle, count } |
envie:removed | envie-button | { productId, variantId, handle, count } |
envie:merged | the client, on document | the merged list — a guest list just became the customer's |
envie:shared | envie-share | { shareToken, url } |
envie:rendered | envie-list | { count } — items currently rendered |
envie:error | any component | { message } — the optimistic update was reverted |
Forward to a data layer
Complete, paste-ready — works with GTM's dataLayer and adapts to anything else:
<script>
window.dataLayer = window.dataLayer || [];
["envie:added", "envie:removed"].forEach(function (type) {
document.addEventListener(type, function (event) {
window.dataLayer.push({
event: type === "envie:added" ? "add_to_wishlist" : "remove_from_wishlist",
product_id: event.detail.productId,
variant_id: event.detail.variantId,
product_handle: event.detail.handle,
wishlist_count: event.detail.count,
});
});
});
</script>In a Liquid theme this goes in theme.liquid (or a custom-code block). In a headless app, register
the same listeners wherever you bootstrap analytics.
GA4 directly
document.addEventListener("envie:added", (event) => {
gtag("event", "add_to_wishlist", {
items: [{ item_id: event.detail.productId, item_variant: event.detail.variantId ?? undefined }],
});
});Headless: subscribe to state instead
If you use @getenvie/client without the components, the reactive snapshot is often more convenient
than events:
import { createEnvie } from "@getenvie/client";
const envie = createEnvie({
mode: "public",
shop: "your-store.myshopify.com",
publicKey: "env_pk_your_store_xxxxxxxx",
});
const unsubscribe = envie.subscribe((state) => {
// { ready, count, items, config } — fires on every change
console.log("wishlist count:", state.count);
});Server-side events
DOM events cover the browser. For your backend — sync, notifications, a CDP — use outbound webhooks: the same interactions delivered to your endpoint, signed, with retries.
Common mistakes
- Listening on the element instead of
document. Auto-injected buttons appear after your script runs; a delegated listener ondocumentcatches them all, whenever they arrive. - Counting
envie:addedas a conversion event by itself. The event fires after the server confirms, but a shopper can toggle rapidly — dedupe byproductIdin your pipeline if your numbers must be exact.
Theming & parts reference
Style every Envie component from your own CSS — parts, state attributes, custom properties, and the styling contract behind them.
Guest → customer merge
How an anonymous wishlist becomes the customer's when a shopper logs in — and what your integration has to do (usually nothing).