PageSourceSearch

https://www.serta.com/scripts/meta-pixel.js

js serta.com collected 2026-10-03 20:00:58 UTC 11,220 bytes, 374 lines download raw bytes

1// Meta Pixel via GTM (Elevar 2.0): dl_user_data, dl_view_item, dl_add_to_cart, dl_begin_checkout.
2
3// Ensure both data layer arrays exist (dataLayer for GTM, ElevarDataLayer for Elevar 2.0 pipe).
4function initDataLayer() {
5  window.dataLayer = window.dataLayer || [];
6  window.ElevarDataLayer = window.ElevarDataLayer || [];
7}
8
9// Push only to ElevarDataLayer; Elevar's handler enriches and forwards the copy to dataLayer.
10function pushToDataLayers(payload) {
11  window.ElevarDataLayer = window.ElevarDataLayer || [];
12  window.ElevarDataLayer.push(payload);
13}
14
15function getDataLayerItemId(productId) {
16  const match = String(productId).match(/^gid:\/\/shopify\/Product\/(\d+)$/);
17  return match ? match[1] : productId;
18}
19
20function getDataLayerVariantId(variantId) {
21  const match = String(variantId || '').match(/^gid:\/\/shopify\/ProductVariant\/(\d+)$/);
22  return match ? match[1] : (variantId || '');
23}
24
25function getFirstValue(...values) {
26  return values.find((value) => value !== undefined && value !== null && value !== '') || '';
27}
28
29function getPriceValue(product) {
30  const rawPrice = getFirstValue(
31    product.productPrice,
32    product.price,
33    product.priceRange?.minVariantPrice?.amount,
34    product.variant?.price?.amount,
35  );
36  const price = parseFloat(rawPrice || 0);
37  return Number.isNaN(price) ? '0.00' : price.toFixed(2);
38}
39
40function getProductImage(product) {
41  return getFirstValue(
42    product.image,
43    product.imageUrl,
44    product.featuredImage?.url,
45    product.variant?.image?.url,
46    product.images?.edges?.[0]?.node?.url,
47  );
48}
49
50function buildElevarProduct(product = {}) {
51  const productId = getFirstValue(product.product_id, product.productId, product.id);
52  const variantId = getFirstValue(
53    product.variant_id,
54    product.variantId,
55    product.variantID,
56    product.variant?.id,
57  );
58  const normalizedProductId = getDataLayerItemId(productId);
59  const normalizedVariantId = getDataLayerVariantId(variantId);
60  const name = getFirstValue(product.productName, product.name, product.title);
61  const sku = getFirstValue(
62    product.sku,
63    product.variant?.sku,
64    normalizedVariantId,
65    normalizedProductId,
66  );
67  const quantity = String(product.quantity || 1);
68  const category = getFirstValue(
69    product.productCategory,
70    product.category,
71    product.productType,
72    product.type,
73  );
74  const variant = getFirstValue(
75    product.variantTitle,
76    product.variantName,
77    product.variant?.title,
78    product.variant,
79  );
80  const brand = getFirstValue(product.brand, product.vendor);
81
82  return {
83    id: sku,
84    name,
85    brand,
86    category,
87    variant,
88    price: getPriceValue(product),
89    quantity,
90    list: product.list || '',
91    product_id: normalizedProductId,
92    variant_id: normalizedVariantId,
93    image: getProductImage(product),
94    url: product.url || '',
95    selling_plan_name: product.selling_plan_name || product.sellingPlanName || 'one-time',
96    item_id: sku,
97    item_name: name,
98    Item_category: category,
99    Item_variant: variant,
100    Item_brand: brand,
101  };
102}
103
104// Push dl_user_data once per page load; Elevar 2.0 requires it before other dl_* events same tick.
105export function initializeUserData() {
106  initDataLayer();
107
108  if (window.elevarUserDataPushed) return;
109
110  const userDataEvent = {
111    event: 'dl_user_data',
112    user_id: null,
113  };
114
115  const isDebugMode = window.location?.hostname?.includes('localhost')
116                     || window.location?.hostname?.includes('hlx.')
117                     || window.location?.hostname?.includes('serta-dev')
118                     || window.location?.hostname?.includes('staging');
119
120  if (isDebugMode) {
121    // eslint-disable-next-line no-console
122    console.log('[Meta Pixel - Debug] Pushing user_data event:', userDataEvent);
123  }
124
125  pushToDataLayers(userDataEvent);
126  window.elevarUserDataPushed = true;
127}
128
129// Track PDP view: push dl_view_item in Elevar 2.0 format with Meta standard params.
130export function trackViewContent(product) {
131  initDataLayer();
132  initializeUserData();
133
134  const productDetail = [buildElevarProduct(product)];
135  const [item] = productDetail;
136  const {
137    id: itemId,
138    name: productName,
139    price: itemPrice,
140    category,
141  } = item;
142  const price = parseFloat(itemPrice);
143  const productId = getFirstValue(product.productId, product.sku, itemId);
144  const productGroup = product.productGroup || 'SSB Products';
145
146  // Skip back-to-back duplicate pushes for the same product/variant (e.g. re-render races).
147  const signature = `${item.product_id}:${item.variant_id}:${price}`;
148  if (window.elevarLastViewItemSignature === signature) return;
149  window.elevarLastViewItemSignature = signature;
150
151  // Clear previous ecommerce data to prevent cross-event contamination.
152  pushToDataLayers({ ecommerce: null });
153  pushToDataLayers({
154    event: 'dl_view_item',
155    ecommerce: {
156      currency: 'USD',
157      currencyCode: 'USD',
158      value: price,
159      items: productDetail,
160      detail: {
161        products: productDetail,
162      },
163    },
164    content_ids: [productId],
165    content_type: 'product',
166    content_name: productName,
167    content_category: category,
168    value: price,
169    currency: 'USD',
170    'dlv - Product View - Name': productName,
171    'dlv - Product View - Category Name': category,
172    'dlv - Product View - SKU': productId,
173    'dlv - Product View - Price': price,
174    'dlv - Product View - Product Group': productGroup,
175    'dlv - Product View - Details Array': productDetail,
176    'dlv - Global - Currency Code': 'USD',
177  });
178
179  if (window.location?.hostname === 'localhost' || window.location?.hostname?.includes('hlx.')) {
180    // eslint-disable-next-line no-console
181    console.log('[Meta Pixel - Elevar] ViewContent (dl_view_item):', {
182      productName,
183      price,
184      products: productDetail,
185    });
186  }
187}
188
189// Track add-to-cart: push dl_add_to_cart in Elevar 2.0 format with Meta standard params.
190export function trackAddToCart(product) {
191  initDataLayer();
192  initializeUserData();
193
194  const cartItem = [buildElevarProduct(product)];
195  const [item] = cartItem;
196  const {
197    id: itemId,
198    name: productName,
199    price: itemPrice,
200    quantity: itemQuantity,
201    category,
202  } = item;
203  const price = parseFloat(itemPrice);
204  const quantity = parseFloat(itemQuantity);
205  const totalValue = price * quantity;
206  const productId = getFirstValue(product.productId, product.sku, itemId);
207  const productGroup = product.productGroup || 'SSB Products';
208
209  // Clear previous ecommerce data to prevent cross-event contamination.
210  pushToDataLayers({ ecommerce: null });
211  pushToDataLayers({
212    event: 'dl_add_to_cart',
213    ecommerce: {
214      currency: 'USD',
215      currencyCode: 'USD',
216      value: totalValue,
217      items: cartItem,
218      add: {
219        products: cartItem,
220      },
221    },
222    content_ids: [productId],
223    content_type: 'product',
224    content_name: productName,
225    content_category: category,
226    value: totalValue,
227    currency: 'USD',
228    num_items: quantity,
229    'dlv - Add to Cart - Name': productName,
230    'dlv - Add to Cart - Category Name': category,
231    'dlv - Add to Cart - SKU': productId,
232    'dlv - Add to Cart - Price': price,
233    'dlv - Add to Cart - Quantity': quantity,
234    'dlv - Add to Cart - Product Group': productGroup,
235    'dlv - Add to Cart - Details Array': cartItem,
236    'dlv - Global - Currency Code': 'USD',
237  });
238
239  if (window.location?.hostname === 'localhost' || window.location?.hostname?.includes('hlx.')) {
240    // eslint-disable-next-line no-console
241    console.log('[Meta Pixel - Elevar] AddToCart (dl_add_to_cart):', {
242      productName,
243      price,
244      quantity,
245      totalValue,
246      products: cartItem,
247    });
248  }
249}
250
251export function trackViewItemList(products = [], list = '') {
252  initDataLayer();
253  initializeUserData();
254
255  const productList = products.map((product) => buildElevarProduct({ ...product, list }));
256  if (productList.length === 0) return;
257
258  const signature = JSON.stringify({
259    list,
260    products: productList.map((product) => `${product.product_id}:${product.variant_id}`),
261  });
262  if (window.elevarLastViewItemList === list) return;
263  window.elevarLastViewItemList = list;
264
265  pushToDataLayers({ ecommerce: null });
266  pushToDataLayers({
267    event: 'dl_view_item_list',
268    ecommerce: {
269      currencyCode: 'USD',
270      impressions: productList,
271      items: productList,
272    },
273  });
274}
275
276export function trackSelectItem(product, list = '') {
277  initDataLayer();
278  initializeUserData();
279
280  const productList = [buildElevarProduct({ ...product, list })];
281  pushToDataLayers({ ecommerce: null });
282  pushToDataLayers({
283    event: 'dl_select_item',
284    ecommerce: {
285      currencyCode: 'USD',
286      click: {
287        actionField: { list },
288        products: productList,
289      },
290      items: productList,
291    },
292  });
293
294  if (window.location?.hostname === 'localhost' || window.location?.hostname?.includes('hlx.')) {
295    // eslint-disable-next-line no-console
296    console.log('[Meta Pixel - Elevar] SelectItem (dl_select_item):', productList[0]);
297  }
298}
299
300// Track checkout start: push dl_begin_checkout with Shopify cart data.
301export function trackBeginCheckout(cartData) {
302  initDataLayer();
303  initializeUserData();
304
305  const cartLines = cartData?.lines?.edges || [];
306  const items = cartLines.map((edge) => {
307    const line = edge?.node || {};
308    const merchandise = line.merchandise || {};
309    const product = merchandise.product || {};
310
311    return buildElevarProduct({
312      sku: product.sku || merchandise.sku || '',
313      product_id: product.id,
314      variant_id: merchandise.id,
315      name: product.title,
316      price: merchandise.price?.amount,
317      quantity: line.quantity || 1,
318      category: product.category?.name,
319      variantTitle: merchandise.title,
320      brand: product.vendor,
321      image: merchandise.image?.url,
322      url: product.handle ? `${window.location.origin}/products/${product.handle}` : '',
323    });
324  });
325
326  const totalValue = items.reduce((sum, item) => sum + (item.price * item.quantity), 0);
327
328  pushToDataLayers({
329    event: 'dl_begin_checkout',
330    ecommerce: {
331      currency: 'USD',
332      currencyCode: 'USD',
333      value: totalValue,
334      items,
335      checkout: {
336        products: items,
337      },
338    },
339    content_ids: items.map((item) => item.id),
340    content_type: 'product',
341    value: totalValue,
342    currency: 'USD',
343    num_items: items.reduce((count, item) => count + Number(item.quantity), 0),
344    'dlv - Begin Checkout - Details Array': items,
345    'dlv - Global - Currency Code': 'USD',
346  });
347
348  if (window.location?.hostname === 'localhost' || window.location?.hostname?.includes('hlx.')) {
349    // eslint-disable-next-line no-console
350    console.log('[Meta Pixel - Elevar] BeginCheckout (dl_begin_checkout):', {
351      totalValue,
352      items,
353    });
354  }
355}
356
357// Legacy shim: map old Meta event names to the Elevar tracker functions.
358export function trackMetaPixelEvent(eventName, eventData = {}) {
359  if (eventName === 'ViewContent') {
360    trackViewContent(eventData);
361  } else if (eventName === 'AddToCart') {
362    trackAddToCart(eventData);
363  }
364}
365
366export default {
367  trackViewContent,
368  trackAddToCart,
369  trackViewItemList,
370  trackSelectItem,
371  trackBeginCheckout,
372  trackMetaPixelEvent,
373  initializeUserData,
374};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.