1(() => { 2 const Tracker = { 3 init: (config) => { 4 Tracker.config = config; 5 Tracker.log(`Initialised`, 'log'); 6 Tracker.nonce = crypto.randomUUID(); 7 window.onload = () => Tracker.setup(); 8 }, 9 refresh: () => { 10 Tracker.setup(); 11 }, 12 setup: () => { 13 Tracker.assignTracker(); 14 Tracker.getPageData(); 15 Tracker.eventBind(); 16 }, 17 assignTracker: () => { 18 window.Tracker = Object.assign(Tracker, window.Tracker); 19 }, 20 urlEvent: () => { 21 if (!Tracker.config.watchers) { 22 return; 23 } 24 const keys = Object.keys(Tracker.config.watchers.params); 25 const searchParams = new URLSearchParams(window.location.search); 26 keys.map((key) => { 27 if ( 28 searchParams.get( 29 Tracker.config.watchers.params[key].paramName 30 ) 31 ) { 32 Tracker.handlers[ 33 Tracker.config.watchers.params[key].eventName 34 ](); 35 let url = new URL(window.location.href); 36 url.searchParams.delete( 37 Tracker.config.watchers.params[key].paramName 38 ); 39 history.replaceState(history.state, '', url.href); 40 } 41 }); 42 }, 43 eventBind: () => { 44 Tracker.urlEvent(); 45 const nodes = [ 46 ...document.querySelectorAll( 47 `[${Tracker.config.selectors.track}]` 48 ) 49 ]; 50 nodes.map((node) => { 51 let el = node, 52 handler = el.getAttribute(Tracker.config.selectors.track), 53 eventType = el.getAttribute(Tracker.config.selectors.type) 54 ? el 55 .getAttribute(Tracker.config.selectors.type) 56 .split('|') 57 : ['click']; 58 if (typeof Tracker.handlers[handler] !== 'undefined') { 59 if (eventType[0] === 'impression') { 60 const observer = new IntersectionObserver((entries) => { 61 entries.forEach((entry) => { 62 if (entry.isIntersecting) { 63 Tracker.handlers[handler](el); 64 } 65 }); 66 }); 67 observer.observe(el); 68 } else if (eventType[0] === 'onload') { 69 Tracker.handlers[handler](el); 70 } else { 71 el.addEventListener( 72 eventType, 73 Tracker.handlers[handler] 74 ); 75 } 76 } else { 77 Tracker.log( 78 `Hanlder ${handler} not found on element: %o`, 79 node 80 ); 81 } 82 }); 83 }, 84 getPageData: () => { 85 const currencyEl = document.querySelector( 86 `[${Tracker.config.selectors.currency}]` 87 ); 88 Tracker.page = {}; 89 if (currencyEl) { 90 if ( 91 window.Tracker.store.currency !== 92 currencyEl.getAttribute( 93 Tracker?.config?.selectors?.currency 94 ) 95 ) { 96 Tracker.store.set( 97 'currency', 98 currencyEl.getAttribute( 99 Tracker?.config?.selectors?.currency 100 ) 101 ); 102 } 103 } else { 104 Tracker.log( 105 `Required attribute ${Tracker?.config?.selectors?.currency} not found. Include ${Tracker.config.selectors.currency}="GBP" (for e.g.) to an element in the DOM.` 106 ); 107 } 108 }, 109 getAttributes: (el) => { 110 const target = el.currentTarget; 111 const store = target?.getAttribute(Tracker.config.selectors.store); 112 const type = target?.getAttribute(Tracker.config.selectors.type); 113 const track = target?.getAttribute(Tracker.config.selectors.track); 114 return { store, type, track }; 115 }, 116 push: (obj, config) => { 117 if (!Tracker.enabled) return; 118 Tracker.log(`Pushed event: ${JSON.stringify(obj)}`, 'log'); 119 if (config?.commerce) { 120 window.dataLayer.push({ commerce: true }); 121 } 122 if (window.dataLayer) { 123 window.dataLayer.push(obj); 124 } 125 }, 126 marshalPubSub: ( 127 operationName, 128 url, 129 eventData, 130 legacyRayId, 131 experiments 132 ) => { 133 const rayId = 134 legacyRayId || Tracker.store.get('rayId')?.value || 'unknown'; 135 const legacyData = { 136 ...eventData, 137 ray_ids: [rayId], 138 nonce: Tracker.nonce, 139 server: { 140 elysium_version: 141 Tracker.trackApiConfig.elysium_config.version 142 }, 143 request: { 144 start_timestamp: Date.now(), 145 url: url 146 }, 147 origin: { 148 referrer: document.referrer 149 }, 150 property: { 151 site_id: Tracker.trackApiConfig.elysium_config.site_id, 152 channel: Tracker.trackApiConfig.elysium_config.channel, 153 subsite: Tracker.trackApiConfig.elysium_config.subsite, 154 locale: Tracker.store.get('locale')?.value 155 }, 156 experiments 157 }; 158 const basket = Tracker.store.get('basket'); 159 const cart = { 160 items: basket?.items?.map((item) => { 161 return { 162 product_group: { 163 id: parseInt(item.id), 164 selected_variant: { 165 price: { 166 currency: Tracker.store.get('currency'), 167 value: parseFloat( 168 item.product.price?.price?.amount
169 ) 170 }, 171 sku: parseInt(item.product.product?.sku) 172 }, 173 total_variants: 174 item.product.product?.variants?.length || null 175 }, 176 quantity: item.quantity 177 }; 178 }), 179 total_size: basket?.totalQuantity || 0, 180 total_price: { 181 currency: Tracker.store.get('currency'), 182 value: parseFloat(basket?.chargePrice?.amount) 183 } 184 }; 185 186 if (cart.items?.length) { 187 legacyData.cart = cart; 188 } 189 190 const payload = { 191 operationName: operationName, 192 metadata: {}, 193 path: url, 194 version: 'altitude', 195 rayId: rayId, 196 currency: 197 Tracker.store.get('currency') || 198 Tracker.store.get('curr')?.value, 199 shippingDestination: Tracker.store.get('ship')?.value, 200 locale: Tracker.store.get('locale')?.value 201 }; 202 203 if (Object.keys(legacyData).length) payload.legacy = legacyData; 204 return payload; 205 }, 206 pushToTrackAPI: async (payload) => { 207 if (!Tracker.enabled) return null; 208 const trackUrl = Tracker.trackApiConfig.trackAPIUrl; 209 if (!trackUrl) return; 210 const dataBlob = new Blob([JSON.stringify(payload)], { 211 type: 'application/json' 212 }); 213 navigator.sendBeacon(trackUrl, dataBlob); 214 }, 215 sendPubSubEvent: async ( 216 operationName, 217 eventData, 218 legacyRayId = null 219 ) => { 220 const experiments = []; 221 if (window.__EXPERIMENTS__) { 222 const chunks = window.__EXPERIMENTS__?.split(','); 223 chunks?.forEach((pair) => { 224 const [name, value] = pair?.split(':'); 225 if (name && value) { 226 experiments.push({ name, value }); 227 } 228 }); 229 } 230 const payload = Tracker.marshalPubSub( 231 operationName, 232 window.location.pathname + window.location.search, 233 eventData, 234 legacyRayId, 235 experiments 236 ); 237 return Tracker.pushToTrackAPI(payload); 238 }, 239 log: (message, type = 'warn') => { 240 if (Tracker?.config?.debug) { 241 type === 'warn' && console.warn('[Tracker]: %s', message); 242 type === 'log' && console.log('[Tracker]: %s', message); 243 } 244 }, 245 translateTarget: (e) => { 246 if (e instanceof Event) { 247 return e.currentTarget.getAttribute( 248 Tracker.config.selectors.store 249 ); 250 } else if (e instanceof HTMLElement) { 251 return e.getAttribute(Tracker.config.selectors.store); 252 } else if (e.store) { 253 return e.store; 254 } else { 255 e; 256 } 257 }, 258 handlers: { 259 performanceData: (CWVObject, perfDataObject) => { 260 const experiments = []; 261 if (window.__EXPERIMENTS__) { 262 const chunks = window.__EXPERIMENTS__?.split(','); 263 chunks?.forEach((pair) => { 264 const [name, value] = pair?.split(':'); 265 if (name && value) { 266 experiments.push({ name, value }); 267 } 268 }); 269 } 270 const perfData = { 271 request: { 272 server_timestamp: null, 273 client_timestamp: new Date(Date.now()).toISOString(), 274 url: window.location.href 275 }, 276 experiments: experiments, 277 errors: [ 278 { 279 type: null, 280 label: null 281 } 282 ], 283 timing: { 284 backend_load_time: 285 perfDataObject?.navigationTiming?.backendLoadTime, 286 cache_time: perfDataObject?.navigationTiming?.cacheTime, 287 connection_time: 288 perfDataObject?.navigationTiming?.connectionTime, 289 dns_time: perfDataObject?.navigationTiming?.dnsTime, 290 dom_interactive_time: 291 perfDataObject?.navigationTiming 292 ?.domInteractiveTime, 293 dom_parsing_time: 294 perfDataObject?.navigationTiming?.domParsingTime, 295 dom_ready_time: 296 perfDataObject?.navigationTiming?.domReadyTime, 297 first_paint_time: 298 perfDataObject?.navigationTiming?.firstPaintTime, 299 frontend_load_time: 300 perfDataObject?.navigationTiming?.frontendLoadTime, 301 load_event_time: 302 perfDataObject?.navigationTiming?.loadEventTime, 303 navigation_time: 304 perfDataObject?.navigationTiming?.navigationTime, 305 redirect_time: 306 perfDataObject?.navigationTiming?.redirectTime, 307 first_contentful_paint_time: CWVObject?.fcp || null, 308 first_input_delay: CWVObject?.fid || null, 309 largest_contentful_paint_time: CWVObject?.lcp || null, 310 first_byte_time: CWVObject?.ttfb || null 311 }, 312 score: { 313 cumulative_layout_shift: CWVObject?.cls || null 314 }, 315 nonce: Tracker.nonce, 316 device: perfDataObject?.device, 317 page: perfDataObject?.page, 318 network: perfDataObject?.network, 319 abtasty: [ 320 { 321 name: null, 322 time_to_first_byte: null, 323 transfer: null, 324 total: null, 325 encoded_file_size: null 326 } 327 ] 328 }; 329 Tracker.pushToTrackAPI({ 330 operationName: 'perfData', 331 metaData: { destination: 'performanceData' }, 332 eventData: perfData 333 }); 334 }, 335 // Page Load 336 pageLoad: () => { 337 const pageAttributesEntry = { 338 mobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( 339 navigator.userAgent 340 ) 341 ? 'yes' 342 : 'no' 343 }; 344 345 const experiments = window.__EXPERIMENTS__; 346 if (experiments) { 347 pageAttributesEntry.experiments = [experiments]; 348 } 349 350 const payload = { 351 event: 'PageLoad', 352 platformType: 'Altitude', 353 pagePath: window.location.pathname, 354 pageAttributes: [pageAttributesEntry], 355 visitorLocation: window.__USRCOUNTRY__ 356 }; 357 358 Tracker.push(payload); 359 }, 360 361 // Cookie Consent 362 cookieModalOpen: () => { 363 const elyEvent = { 364 event: 'elysiumEvent', 365 eventData: {
366 eventCategory: 'Cookie Modal', 367 eventAction: 'Shown', 368 eventLabel: 'Accept Cookie Button', 369 eventPage: window?.location?.pathname 370 } 371 }; 372 Tracker.push(elyEvent); 373 }, 374 375 cookieModalClicked: () => { 376 const elyEvent = { 377 event: 'elysiumEvent', 378 eventData: { 379 eventCategory: 'Cookie Modal', 380 eventAction: 'Clicked', 381 eventLabel: 'Accept Cookie Button', 382 eventPage: window?.location?.pathname 383 } 384 }; 385 Tracker.push(elyEvent); 386 }, 387 388 // ReEngagement Modal 389 reEngOpen: () => { 390 const elyEvent = { 391 event: 'elysiumEvent', 392 eventData: { 393 eventCategory: 'reEngagement Tooltip Modal', 394 eventAction: 'Shown', 395 eventLabel: 'reEngagement Modal Message', 396 eventPage: window?.location?.pathname 397 } 398 }; 399 Tracker.push(elyEvent); 400 }, 401 402 reEngClicked: (el) => { 403 const elyEvent = { 404 event: 'elysiumEvent', 405 eventData: { 406 eventCategory: 'reEngagement Tooltip Modal', 407 eventAction: 'Clicked', 408 eventLabel: 'Continue Modal Button', 409 eventPage: window?.location?.pathname 410 } 411 }; 412 Tracker.push(elyEvent); 413 }, 414 415 reEngComplete: (el) => { 416 const elyEvent = { 417 event: 'customEvent', 418 eventData: { 419 eventCategory: 'newsletter', 420 eventAction: 'successful sign-up', 421 eventPage: window?.location?.pathname 422 } 423 }; 424 425 Tracker.push(elyEvent); 426 }, 427 428 // Rewards and Loyalty 429 rewardsOptIn: () => { 430 const elyEvent = { 431 event: 'customEvent', 432 eventData: { 433 eventCategory: 'loyalty', 434 eventAction: 'successful sign-up', 435 eventPage: window?.location?.pathname 436 } 437 }; 438 439 Tracker.push(elyEvent); 440 }, 441
442 // Widget Track 443 widgetTrack: (e) => { 444 const widgetKey = e.parentElement.dataset.component; 445 446 const elyEvent = { 447 event: 'elysiumEvent', 448 eventData: { 449 eventCategory: 'Widget Track', 450 eventAction: 'viewed', 451 eventLabel: widgetKey, 452 eventLabelValue: 453 Tracker.store.get('widgets')[widgetKey], 454 eventPage: window?.location?.pathname 455 } 456 }; 457 458 Tracker.push(elyEvent); 459 }, 460 461 widgetClick: (el) => { 462 let widget = Tracker.translateTarget(el); 463 464 const elyEvent = { 465 event: 'elysiumEvent', 466 eventData: { 467 eventCategory: 'Widget Track', 468 eventAction: 'clicked', 469 eventLabel: widget, 470 eventLabelValue: Tracker.store.get('widgets')[widget], 471 eventPage: window?.location?.pathname 472 } 473 }; 474 if (widget !== 'ProductListWidget') { 475 Tracker.push(elyEvent); 476 } 477 }, 478 479 // Navigation 480 navigationHeader: (el) => { 481 const elyEvent = { 482 event: 'elysiumEvent', 483 eventData: { 484 eventCategory: 'Navigation Header', 485 eventAction: `Clicked ${window.tenantConfig?.application?.siteName}`, 486 eventLabel: 487 window.tenantConfig?.application?.livedomain, 488 eventPage: window?.location?.pathname 489 } 490 }; 491 Tracker.push(elyEvent); 492 }, 493 494 navigationMenu: (el) => { 495 const mainCategory = el.target.innerText; 496 497 const elyEvent = { 498 event: 'elysiumEvent', 499 eventData: { 500 eventCategory: 'Navigation Header', 501 eventAction: `Clicked ${mainCategory}` 502 } 503 }; 504 Tracker.push(elyEvent); 505 }, 506 507 navigationSubnav: (el) => { 508 const subCategory = el.target.innerText; 509 510 const elyEvent = { 511 event: 'elysiumEvent', 512 eventData: { 513 eventCategory: 'Navigation Header', 514 eventAction: `Clicked ${subCategory}` 515 } 516 }; 517 Tracker.push(elyEvent); 518 }, 519 520 navigationButton: (el) => { 521 const button = Tracker.translateTarget(el); 522 523 const elyEvent = { 524 event: 'elysiumEvent', 525 eventData: { 526 eventCategory: 'Navigation Header', 527 eventAction: `Clicked ${button}` 528 } 529 }; 530 Tracker.push(elyEvent); 531 }, 532 533 clickUSP: (el) => { 534 let usp = Tracker.translateTarget(el); 535 536 const elyEvent = { 537 event: 'elysiumEvent', 538 eventData: { 539 eventCategory: 'Widget Track', 540 eventAction: usp,
541 eventLabel: 'Responsive USP bar', 542 eventPage: window?.location?.pathname 543 } 544 }; 545 Tracker.push(elyEvent); 546 }, 547 548 // Search 549 search: (e) => { 550 const store = Tracker.translateTarget(e); 551 // const searchInfo = window.Tracker.store.get('searchInfo') 552 // const elyEvent = { 553 // event: 'elysiumEvent', 554 // eventData: { 555 // eventCategory: 'Navigation Header', 556 // eventAction: `Clicked ${searchInfo?.input ?? ''}`, 557 // eventLabel: 558 // window?.location?.pathname + window?.location?.search, 559 // eventPage: window?.location?.pathname 560 // } 561 // } 562 // Tracker.push(elyEvent) 563 564 const pageData = Tracker.store.get(store); 565 Tracker.sendPubSubEvent( 566 'Search', 567 { 568 event: { 569 type: 'search' 570 }, 571 page: { 572 search: { 573 query: pageData.query || '', 574 total_results: pageData.total 575 }, 576 items: pageData.products?.map((product) => { 577 return { 578 product_group: { 579 selected_variant: { 580 price: { 581 currency: 582 product?.defaultVariant 583 ?.price?.price 584 ?.currency, 585 value: parseFloat( 586 product?.defaultVariant 587 ?.price?.price?.amount
588 ) 589 }, 590 sku: parseInt(product?.sku) 591 }, 592 total_variants: 593 product?.variants?.length 594 } 595 }; 596 }) 597 } 598 }, 599 pageData.rayId 600 ); 601 }, 602 suggestedSearchQueries: (el) => { 603 let query = Tracker.translateTarget(el); 604 605 const elyEvent = { 606 event: 'elysiumEvent', 607 eventData: { 608 eventCategory: 'Navigation Header', 609 eventAction: `Clicked ${query}`, 610 eventLabel: `/search/?q=${query}`, 611 eventPage: window?.location?.pathname 612 } 613 }; 614 Tracker.push(elyEvent); 615 }, 616 617 suggestedSearchProduct: (el) => { 618 const sku = Tracker.translateTarget(el); 619 const product = Tracker.store.get('suggestedProducts')[sku]; 620 621 const elyEvent = { 622 event: 'elysiumEvent', 623 eventData: { 624 eventCategory: 'Navigation Header', 625 eventAction: `Clicked ${product?.product_id}:${product?.product_name}`, 626 eventLabel: product?.url, 627 eventPage: window?.location?.pathname 628 } 629 }; 630 Tracker.push(elyEvent); 631 }, 632 633 // Basket 634 goToBasket: (el) => { 635 const key = Tracker.translateTarget(el); 636 637 const quantity = Tracker.store.get(key); 638 639 const elyEvent = { 640 event: 'Link', 641 eventData: { 642 eventCategory: 'Link', 643 eventAction: 'Go To Basket', 644 eventLabel: quantity, 645 eventPage: window?.location?.pathname 646 } 647 }; 648 Tracker.push(elyEvent); 649 }, 650 651 viewBasket: () => { 652 const elyEvent = { 653 event: 'elysiumEvent', 654 eventData: { 655 eventCategory: 'Navigation Header', 656 eventAction: 'Clicked View Basket', 657 eventPage: window?.location?.pathname 658 } 659 }; 660 Tracker.push(elyEvent); 661 }, 662 663 addToCart: (e) => { 664 let data = Tracker.store.get('products')[e]; 665 666 const elyEvent = { 667 event: 'elysiumEvent', 668 eventData: { 669 eventCategory: 'Product | AddToBasket', 670 eventAction: 'success', 671 eventLabel: data?.item_id, 672 eventLabelValue: data.item_name 673 }, 674 eventPage: window?.location?.pathname 675 }; 676 const ecommerceEvent = { 677 event: 'ecom_event', 678 event_name: 'add_to_cart', 679 ecommerce: { 680 currencyCode: data.currency ?? '', 681 value: data?.value, 682 items: [ 683 { 684 item_id: data.item_id ?? '', 685 item_name: data.item_name ?? '', 686 item_brand: data.item_brand ?? '', 687 price: data.price ?? 'unknown', 688 index: data.index, 689 discount: data?.discount, 690 affiliation: data?.affiliation, 691 coupon: data.coupon, 692 item_category: data?.item_category, 693 item_list_name: data?.item_list_name, 694 item_variant: data?.variant, 695 quantity: data.quantity ?? 0 696 } 697 ] 698 } 699 }; 700 Tracker.push(ecommerceEvent, { commerce: true }); 701 Tracker.push(elyEvent); 702 const items = [data]; 703 Tracker.sendPubSubEvent('AddToCart', { 704 event: { 705 type: 'cart_interaction_event', 706 subtype: 'initial_add', 707 items: items.map((item) => ({ 708 product_group: { 709 selected_variant: { 710 price: { 711 currency: Tracker.store.get('currency'), 712 value: 713 parseFloat(item.price) * 714 item.quantity 715 }, 716 sku: parseInt(item.item_id) 717 } 718 }, 719 quantity: item.quantity 720 })) 721 } 722 }); 723 }, 724 725 removeFromCart: (e) => { 726 let data = Tracker.store.get('products')[e]; 727 const elyEvent = { 728 event: 'elysiumEvent', 729 eventData: { 730 eventCategory: 'Product | Remove From Basket', 731 eventAction: 'success', 732 eventLabel: data?.item_id, 733 eventLabelValue: data.item_name 734 }, 735 eventPage: window?.location?.pathname 736 }; 737 const ecommerceEvent = { 738 event: 'ecom_event', 739 event_name: 'remove_from_cart', 740 ecommerce: { 741 currencyCode: data?.currency ?? '', 742 value: data?.value, 743 items: [ 744 { 745 item_id: data.item_id ?? '', 746 item_name: data.item_name ?? '', 747 item_brand: data.item_brand ?? '', 748 price: data.price ?? 'unknown', 749 index: data.index, 750 discount: data?.discount, 751 affiliation: data?.affiliation, 752 coupon: data.coupon, 753 item_category: data?.item_category, 754 item_list_name: data?.item_list_name, 755 item_variant: data?.variant, 756 quantity: data.quantity ?? 0 757 } 758 ] 759 } 760 }; 761 Tracker.push(ecommerceEvent, { commerce: true }); 762 Tracker.push(elyEvent); 763 const items = [data]; 764 Tracker.sendPubSubEvent('RemoveFromCart', { 765 event: { 766 type: 'cart_interaction_event', 767 subtype: 'trash', 768 items: items.map((item) => ({ 769 product_group: { 770 selected_variant: { 771 price: { 772 currency: Tracker.store.get('currency'), 773 value: 774 parseFloat(item.price) * 775 item.quantity 776 }, 777 sku: parseInt(item.item_id) 778 } 779 }, 780 quantity: item.quantity 781 })) 782 } 783 }); 784 }, 785 786 goToCheckout: () => { 787 const event = { 788 event: 'elysiumEvent', 789 event_name: 'go_to_checkout', 790 eventData: { 791 eventAction: 'Go To Checkout' 792 } 793 }; 794 795 Tracker.push(event); 796 }, 797 798 basketProductClick: (e) => { 799 let clickedItem = Tracker.translateTarget(e); 800 const item = Tracker.store.get('products')[clickedItem]; 801 802 const elyEvent = { 803 event: 'elysiumEvent', 804 eventData: { 805 eventCategory: 'Product | AddToBasket', 806 eventAction: 'success', 807 eventLabel: clickedItem, 808 eventLabelValue: item?.item_name 809 }, 810 eventPage: window?.location?.pathname 811 }; 812 813 Tracker.push(elyEvent); 814 }, 815 816 viewFreeGift: (e) => { 817 const id = Tracker.translateTarget(e); 818 const elyEvent = { 819 event: 'elysiumEvent', 820 eventData: { 821 eventCategory: 'freeProductSelection', 822 eventAction: 'ViewedFreeGift', 823 eventLabel: id 824 }, 825 eventPage: window?.location?.pathname 826 }; 827 828 Tracker.push(elyEvent); 829 }, 830 831 selectFreeGift: (e) => { 832 const elyEvent = { 833 event: 'elysiumEvent', 834 eventData: { 835 eventCategory: 'freeProductSelection', 836 eventAction: 'Add Item', 837 eventLabel: e 838 }, 839 eventPage: window?.location?.pathname 840 }; 841 842 Tracker.push(elyEvent); 843 }, 844 845 removeFreeGift: (e) => { 846 const elyEvent = { 847 event: 'elysiumEvent', 848 eventData: { 849 eventCategory: 'freeProductSelection', 850 eventAction: 'Removing Item', 851 eventLabel: e 852 }, 853 eventPage: window?.location?.pathname 854 }; 855 Tracker.push(elyEvent); 856 }, 857 858 applyCouponSuccess: (e) => { 859 let coupon = Tracker.translateTarget(e); 860 861 const elyEvent = { 862 event: 'elysiumEvent', 863 eventData: { 864 eventCategory: 'Discount codes', 865 eventAction: 'Valid', 866 eventLabel: coupon, 867 eventPage: window?.location?.pathname 868 } 869 }; 870 871 Tracker.push(elyEvent); 872 Tracker.handlers.applyDiscountCode({ message: e.message }); 873 }, 874 875 applyCouponFailure: (e) => { 876 const elyEvent = { 877 event: 'elysiumEvent', 878 eventData: { 879 eventCategory: 'Discount codes', 880 eventAction: 'Inactive', 881 eventLabel: e.promoCode, 882 eventPage: window?.location?.pathname 883 } 884 }; 885 Tracker.push(elyEvent); 886 Tracker.handlers.applyDiscountCode({ message: e.errorMessage }); 887 }, 888 applyDiscountCode: (e) => { 889 const messages = [e.message]; 890 891 Tracker.sendPubSubEvent('ApplyDiscountCodeToBasket', { 892 event: { 893 type: 'discount_code_event' 894 }, 895 errors: messages 896 .filter( 897 (message) => 898 message && 899 ![ 900 'OFFER_APPLIED', 901 'CODE_APPLIED', 902 'SELECT_YOUR_SAMPLE_APPLIED', 903 'REFERRAL_CODE_INSERTED', 904 'UPSELL' 905 ].includes(message) 906 ) 907 .map((message) => { 908 let label; 909 switch (message) { 910 case 'CODE_INVALID': 911 label = 'not_found'; 912 break; 913 case 'CODE_EXPIRED': 914 label = 'expired'; 915 break; 916 case 'CODE_VALID_BUT_NOT_APPLICABLE_TO_BASKET': 917 label = 'not_applicable_to_basket_content'; 918 break; 919 case 'REFERRER_NOT_ELIGIBLE':
920 label = 'invalid_referrer'; 921 break; 922 case 'PRODUCT_OUT_OF_STOCK': 923 label = 'gift_not_in_stock'; 924 break; 925 case 'BETTER_OFFER_ALREADY_APPLIED': 926 label = 'better_offer_applied'; 927 break; 928 case 'PROMO_CODE_ALREADY_USED': 929 label = 'no_redemptions_left'; 930 break; 931 case 'REFERRAL_CODE_NEEDS_REGISTRATION': 932 label = 'customer_not_logged_in'; 933 break; 934 case 'REFEREE_NOT_ELIGIBLE': 935 label = 'customer_does_not_qualify'; 936 break; 937 default: 938 label = 'unknown_error_type'; 939 } 940 return { 941 type: 'discount_code_error', 942 label 943 }; 944 }) 945 }); 946 },
947 // Wish list 948 wishlistLoggedout: (el) => { 949 const elyEvent = { 950 event: 'elysiumEvent', 951 eventData: { 952 eventCategory: 'Wishlist Engagement', 953 eventAction: 'Clicked add to wishlist | Logged out', 954 eventLabel: el, 955 eventPage: window?.location?.pathname 956 } 957 }; 958 Tracker.push(elyEvent); 959 }, 960 961 wishlistLogin: (el) => { 962 const elyEvent = { 963 event: 'elysiumEvent', 964 eventData: { 965 eventCategory: 'Wishlist Engagement', 966 eventAction: 'clicked login link', 967 eventLabel: productId, 968 eventPage: window?.location?.pathname 969 } 970 }; 971 Tracker.push(elyEvent); 972 }, 973 974 wishlistRegister: () => { 975 const elyEvent = { 976 event: 'elysiumEvent', 977 eventData: { 978 eventCategory: 'Wishlist Engagement', 979 eventAction: 'clicked register link', 980 eventLabel: productId, 981 eventLabeValue: productName, 982 eventPage: window?.location?.pathname 983 } 984 }; 985 Tracker.push(elyEvent); 986 }, 987 988 wishlistAdded: (el) => { 989 let productId; 990 let productName; 991 const productlist = window.Tracker.store.get('productList'); 992 if (productlist) { 993 productId = productlist.items[el].item_id; 994 productName = productlist.items[el].item_name; 995 } 996 997 if (window.Tracker.store.get(el)) { 998 productId = window.Tracker.store.get(el).item_id; 999 productName = window.Tracker.store.get(el).item_name; 1000 } 1001 1002 const elyEvent = { 1003 event: 'elysiumEvent', 1004 eventData: { 1005 eventCategory: 'Wishlist Engagement', 1006 eventAction: 'added to wishlist', 1007 eventLabel: productId, 1008 eventPage: window?.location?.pathname 1009 } 1010 }; 1011 Tracker.push(elyEvent); 1012 Tracker.sendPubSubEvent('AddToWishlist', { 1013 event: { 1014 type: 'wishlist_interaction_event', 1015 subtype: 'initial_add', 1016 items: [ 1017 { 1018 product_group: { 1019 id: parseInt(el) 1020 }, 1021 quantity: 1 1022 } 1023 ] 1024 } 1025 }); 1026 }, 1027 1028 wishlistRemove: ({ sku, rayId }) => { 1029 let productId; 1030 let productName; 1031 const productlist = window.Tracker.store.get('productList'); 1032 if (productlist) { 1033 productId = productlist.items[sku].item_id; 1034 productName = productlist.items[sku].item_name; 1035 } 1036 1037 if (window.Tracker.store.get(sku)) { 1038 productId = window.Tracker.store.get(sku).item_id; 1039 productName = window.Tracker.store.get(sku).item_name; 1040 } 1041 1042 const elyEvent = { 1043 event: 'elysiumEvent', 1044 eventData: { 1045 eventCategory: 'Wishlist Engagement', 1046 eventAction: 'removed from wishlist', 1047 eventLabel: productId, 1048 eventPage: window?.location?.pathname 1049 } 1050 }; 1051 Tracker.push(elyEvent); 1052 Tracker.sendPubSubEvent( 1053 'RemoveFromWishlist', 1054 { 1055 event: { 1056 type: 'wishlist_interaction_event', 1057 subtype: 'trash', 1058 items: [ 1059 { 1060 product_group: { 1061 id: parseInt(sku) 1062 }, 1063 quantity: 1 1064 } 1065 ] 1066 } 1067 }, 1068 rayId 1069 ); 1070 }, 1071 1072 // PLP 1073 viewItemList: () => { 1074 const list = window.Tracker.store.get('productList'); 1075 1076 const gaEvent = { 1077 event: 'view_item_list', 1078 currencyCode: Tracker.store.get('currency'), 1079 ecommerce: { 1080 item_list_id: list?.id ?? '', 1081 item_list_name: list?.title ?? '', 1082 items: list.items && Object.values(list.items) 1083 } 1084 }; 1085 Tracker.push(gaEvent); 1086 }, 1087 1088 ReadMoreClicked: () => { 1089 const elyEvent = { 1090 event: 'elysiumEvent', 1091 eventData: { 1092 eventCategory: 'Read More Button', 1093 eventAction: `Clicked`, 1094 eventPage: window?.location?.pathname 1095 } 1096 }; 1097 Tracker.push(elyEvent); 1098 }, 1099 1100 selectItem: (el) => { 1101 const item = Tracker.translateTarget(el); 1102 const product = Tracker.store.get('productList').items; 1103 const elyEvent = { 1104 event: 'elysiumEvent', 1105 eventData: { 1106 eventCategory: 'List Page Navigation', 1107 eventAction: ` ${product[item]?.url}| Click product image`, 1108 eventLabel: product[item]?.item_id, 1109 eventPage: window?.location?.pathname 1110 } 1111 }; 1112 1113 const gaEvent = { 1114 event: 'select_item', 1115 ecommerce: { 1116 item_list_id: product[item].item_list ?? '', 1117 item_list_name: product[item].title ?? '', 1118 items: [ 1119 { 1120 item_id: product[item].item_id, 1121 item_list: product[item].item_list, 1122 item_brand: product[item].brand, 1123 price: product[item].price, 1124 value: product[item].value, 1125 discount: product[item].discount, 1126 coupon: product[item].coupon, 1127 affiliation: product[item].affiliation, 1128 index: product[item].index, 1129 item_list_id: product[item].item_id, 1130 item_list_name: product[item].item_list, 1131 item_variant: product[item].variant, 1132 quantity: 1 1133 } 1134 ] 1135 } 1136 }; 1137 Tracker.push(elyEvent); 1138 Tracker.push(gaEvent); 1139 }, 1140 1141 showFilter: () => { 1142 const elyEvent = { 1143 event: 'elysiumEvent', 1144 eventData: { 1145 eventCategory: 'responsiveFacets', 1146 eventAction: 'Opens', 1147 eventPage: window?.location?.pathname 1148 } 1149 }; 1150 Tracker.push(elyEvent); 1151 }, 1152 1153 closeFilter: () => { 1154 const elyEvent = { 1155 event: 'elysiumEvent', 1156 eventData: { 1157 eventCategory: 'responsiveFacets', 1158 eventAction: 'Closes', 1159 eventPage: window?.location?.pathname 1160 } 1161 }; 1162 Tracker.push(elyEvent); 1163 }, 1164 1165 filterOpen: () => { 1166 const event = { 1167 event: 'elysiumEvent', 1168 event_name: 'filter_open', 1169 eventData: { 1170 eventCategory: 'responsiveFacets', 1171 eventAction: 'Opens', 1172 type: 'amino acids', 1173 eventPage: window?.location?.pathname 1174 } 1175 }; 1176 1177 Tracker.push(event); 1178 }, 1179 1180 filter: (e) => { 1181 const elyEvent = { 1182 event: 'elysiumEvent', 1183 eventData: { 1184 eventCategory: 'responsiveFacets', 1185 eventAction: 'add', 1186 eventLabel: e, 1187 eventPage: window?.location?.pathname 1188 } 1189 }; 1190 Tracker.push(elyEvent); 1191 }, 1192 1193 filterRemoved: (el) => { 1194 const elyEvent = { 1195 event: 'elysiumEvent', 1196 eventData: { 1197 eventCategory: 'responsiveFacets', 1198 eventAction: 'Removes', 1199 eventLabel: el.eventCategory, 1200 eventPage: window?.location?.pathname 1201 } 1202 }; 1203 Tracker.push(elyEvent); 1204 }, 1205 1206 filterClear: (e) => { 1207 const elyEvent = { 1208 event: 'elysiumEvent', 1209 eventData: { 1210 eventCategory: 'responsiveFacets', 1211 eventAction: 'remove', 1212 eventLabel: 'all facets', 1213 eventPage: window?.location?.pathname 1214 } 1215 }; 1216 Tracker.push(elyEvent); 1217 }, 1218 1219 sortByOpen: () => { 1220 const elyEvent = { 1221 event: 'elysiumEvent', 1222 eventData: { 1223 eventCategory: 'Facet Engagement', 1224 eventAction: 'Opens Sort By', 1225 eventPage: window?.location?.pathname 1226 } 1227 }; 1228 Tracker.push(elyEvent); 1229 }, 1230 1231 sortByClose: (el) => { 1232 const elyEvent = { 1233 event: 'elysiumEvent', 1234 eventData: { 1235 eventCategory: 'Facet Engagement', 1236 eventAction: 'Closes Sort By', 1237 eventPage: window?.location?.pathname 1238 } 1239 }; 1240 Tracker.push(elyEvent); 1241 }, 1242 1243 sortByClick: (el) => { 1244 const sortType = Tracker.translateTarget(el); 1245 1246 const elyEvent = { 1247 event: 'elysiumEvent', 1248 eventData: { 1249 eventCategory: 'Facet Engagement', 1250 eventAction: 'Selects Sort By', 1251 eventLabel: sortType, 1252 eventPage: window?.location?.pathname 1253 } 1254 }; 1255 Tracker.push(elyEvent); 1256 }, 1257 1258 viewPromotion: (e) => { 1259 let promo = Tracker.translateTarget(e); 1260 1261 const elyEvent = { 1262 event: 'elysiumEvent', 1263 eventData: { 1264 eventCategory: 'Pap | papBanner', 1265 eventAction: 'Viewed',
1266 eventLabel: 'papBanner component', 1267 eventPage: window?.location?.pathname 1268 } 1269 }; 1270 1271 const gaEvent = { 1272 event: 'ecom_event', 1273 event_name: 'view_promotion', 1274 ecommerce: { 1275 items: [ 1276 { 1277 promotion_id: '', 1278 promotion_name: promo, 1279 creative_name: '', 1280 creative_slot: '', 1281 location_id: '' 1282 } 1283 ] 1284 } 1285 }; 1286 1287 Tracker.push(elyEvent); 1288 Tracker.push(gaEvent); 1289 }, 1290 1291 promoClick: (el) => { 1292 const promo = Tracker.translateTarget(el); 1293 const elyEvent = { 1294 event: 'elysiumEvent', 1295 eventData: { 1296 eventCategory: 'Pap | papBanner', 1297 eventAction: 'Clicked', 1298 eventLabel: 'papBanner component', 1299 eventPage: window?.location?.pathname 1300 } 1301 }; 1302 1303 const gaEvent = { 1304 event: 'ecom_event', 1305 event_name: 'select_promotion', 1306 ecommerce: { 1307 items: [ 1308 { 1309 promotion_id: '', 1310 promotion_name: promo, 1311 creative_name: '', 1312 creative_slot: '', 1313 location_id: '' 1314 } 1315 ] 1316 } 1317 }; 1318 Tracker.push(gaEvent); 1319 Tracker.push(elyEvent); 1320 }, 1321 1322 promoButtonClick: (e) => { 1323 const promo = Tracker.translateTarget(e); 1324 1325 const elyEvent = { 1326 event: 'elysiumEvent', 1327 eventData: { 1328 eventCategory: 'Pap | papDescriptionCTA', 1329 eventAction: 'Clicked', 1330 eventLabel: 'papDescription component', 1331 eventPage: window?.location?.pathname 1332 } 1333 }; 1334 1335 Tracker.push(elyEvent); 1336 }, 1337 1338 // PDP 1339 viewItem: (e) => { 1340 let itemSku = Tracker.translateTarget(e); 1341 let data = Tracker.store.get('products')[itemSku]; 1342 1343 const elyEvent = { 1344 event: 'elysiumEvent', 1345 event_name: 'view_item', 1346 eventData: { 1347 eventCategory: 'Product | Viewed', 1348 eventAction: 'Viewed', 1349 eventLabel: itemSku, 1350 eventLabelValue: [Tracker.store.get(itemSku)], 1351 eventPage: window?.location?.pathname 1352 } 1353 }; 1354 const gaEvent = { 1355 event: 'ecom_event', 1356 event_name: 'view_items', 1357 ecommerce: { 1358 currencyCode: Tracker.store.get('currency') ?? '', 1359 value: data?.value, 1360 items: [ 1361 { 1362 item_id: data.item_id ?? '', 1363 item_name: data.item_name ?? '', 1364 item_brand: data.item_brand ?? '', 1365 price: data.price ?? 'unknown', 1366 index: data.index, 1367 discount: data?.discount, 1368 affiliation: data?.affiliation, 1369 coupon: data?.coupon, 1370 item_category: data?.item_category, 1371 item_list_name: data?.item_list_name, 1372 item_variant: data?.variant, 1373 quantity: data.quantity ?? 0 1374 } 1375 ] 1376 } 1377 }; 1378 Tracker.push(gaEvent); 1379 Tracker.push(elyEvent); 1380 }, 1381 1382 productDesView: () => { 1383 const elyEvent = { 1384 event: 'elysiumEvent', 1385 eventData: { 1386 eventCategory: 'Product | Description', 1387 eventAction: 'Viewed', 1388 eventLabel: 'productDescription component', 1389 eventPage: window?.location?.pathname 1390 } 1391 }; 1392 Tracker.push(elyEvent); 1393 }, 1394 1395 productImageScrolled: (el) => { 1396 const imgInx = Tracker.translateTarget(el); 1397 const indexInfo = window.Tracker.store.get('imageIndex'); 1398 1399 const elyEvent = { 1400 event: 'elysiumEvent', 1401 eventData: { 1402 eventCategory: 'ProductImageCarousel', 1403 eventAction: 'scroll', 1404 eventLabel: `Scrolled to image ${indexInfo?.index} `, 1405 eventPage: window?.location?.pathname 1406 } 1407 }; 1408 Tracker.push(elyEvent); 1409 }, 1410
1411 productThumbnailClicked: (el) => { 1412 const elyEvent = { 1413 event: 'elysiumEvent', 1414 eventData: { 1415 eventCategory: 'athenaProductImageCarousel', 1416 eventAction: 'click', 1417 eventLabel: `thumbnail`, 1418 eventLabelValue: 'index', 1419 eventPage: window?.location?.pathname 1420 } 1421 }; 1422 Tracker.push(elyEvent); 1423 }, 1424 1425 productDesClick: (el) => { 1426 const eventCategory = el.target.dataset.trackingPush; 1427 1428 const elyEvent = { 1429 event: 'elysiumEvent', 1430 eventData: { 1431 eventCategory: 'Product | Description', 1432 eventAction: 'Clicked', 1433 eventLabel: `productDescription component clicked tab ${eventCategory}`, 1434 eventPage: window?.location?.pathname 1435 } 1436 }; 1437 Tracker.push(elyEvent); 1438 }, 1439 1440 reviewViewed: () => { 1441 const elyEvent = { 1442 event: 'elysiumEvent', 1443 eventData: { 1444 eventCategory: 'Product | Review', 1445 eventAction: 'Viewed', 1446 eventLabel: 'athenaProductReviews component', 1447 eventPage: window?.location?.pathname 1448 } 1449 }; 1450 Tracker.push(elyEvent); 1451 }, 1452 1453 reviewVoted: (el) => { 1454 const elyEvent = { 1455 event: 'elysiumEvent', 1456 eventData: { 1457 eventCategory: 'Product | Voted', 1458 eventAction: 'Voted', 1459 eventLabel: `athenaProductReviews component voted ${el.voted} ${el.id}`, 1460 eventPage: window?.location?.pathname 1461 } 1462 }; 1463 Tracker.push(elyEvent); 1464 }, 1465 1466 reviewReported: (el) => { 1467 const elyEvent = { 1468 event: 'elysiumEvent', 1469 eventData: { 1470 eventCategory: 'Product | Reported', 1471 eventAction: 'Reported', 1472 eventLabel: `athenaProductReviews component reported ${el.id}`, 1473 eventPage: window?.location?.pathname 1474 } 1475 }; 1476 Tracker.push(elyEvent); 1477 }, 1478 1479 reviewCreated: (el) => { 1480 const elyEvent = { 1481 event: 'elysiumEvent', 1482 eventData: { 1483 eventCategory: 'Product | Reported', 1484 eventAction: 'Reported', 1485 eventLabel: `athenaProductReviews component reported ${el?.product_id}`, 1486 eventPage: window?.location?.pathname 1487 } 1488 }; 1489 Tracker.push(elyEvent); 1490 }, 1491 1492 reviewPage: (el) => { 1493 const elyEvent = { 1494 event: 'elysiumEvent', 1495 eventData: { 1496 eventCategory: 'Product | Review', 1497 eventAction: 1498 el === 'next' 1499 ? 'Next Review Page' 1500 : 'Previous Review Page', 1501 eventLabel: `athenaProductReviews component go ${el} page`, 1502 eventPage: window?.location?.pathname 1503 } 1504 }; 1505 Tracker.push(elyEvent); 1506 }, 1507 1508 // PDP 1509 productImageNav: (el) => { 1510 const gaEvent = { 1511 event: 'product_image_nav', 1512 eventData: { 1513 action: `${el?.action} image`, 1514 product_id: el.id, 1515 product_name: el.title 1516 } 1517 }; 1518 1519 const elyEvent = { 1520 event: 'elysiumEvent', 1521 category: 'ProductImageCarousel', 1522 action: 'click', 1523 label: `${el?.action} image`, 1524 page: window?.location?.pathname 1525 }; 1526 Tracker.push(elyEvent); 1527 Tracker.push(gaEvent); 1528 }, 1529 1530 sizeGuideClick: () => { 1531 const gaEvent = { 1532 event: 'product_size_guide', 1533 eventData: { 1534 action: 'Clicked', 1535 component: 'productSizeGuide component clicked button' 1536 } 1537 }; 1538 1539 const elyEvent = { 1540 event: 'elysiumEvent', 1541 category: 'Product | Size Guide', 1542 action: 'Clicked', 1543 label: 'productSizeGuide', 1544 page: window?.location?.pathname 1545 }; 1546 Tracker.push(elyEvent); 1547 Tracker.push(gaEvent); 1548 }, 1549 1550 sizeGuideModalOpen: () => { 1551 const gaEvent = { 1552 event: 'product_size_guide_viewed', 1553 eventData: { 1554 component: 'product size guide modal', 1555 path: window?.location?.pathname 1556 } 1557 }; 1558 1559 const elyEvent = { 1560 event: 'elysiumEvent', 1561 category: 'Product | Size Guide modal', 1562 action: 'Shown', 1563 label: 'productSizeGuide', 1564 page: window?.location?.pathname 1565 }; 1566 Tracker.push(elyEvent); 1567 Tracker.push(gaEvent); 1568 }, 1569 1570 sizeGuideModalClose: () => { 1571 const gaEvent = { 1572 event: 'product_size_guide_closed', 1573 eventData: { 1574 component: 'product size guide modal', 1575 path: window?.location?.pathname 1576 } 1577 }; 1578 1579 const elyEvent = { 1580 event: 'elysiumEvent', 1581 category: 'Product | Size Guide modal', 1582 action: 'Closed', 1583 label: 'product Size Guide', 1584 page: window?.location?.pathname 1585 }; 1586 Tracker.push(elyEvent); 1587 Tracker.push(gaEvent); 1588 }, 1589 updateMarketingPreferences: ({ rayId }) => { 1590 Tracker.sendPubSubEvent( 1591 'MarketingPreferenceUpdated', 1592 { 1593 event: { 1594 type: 'account_update', 1595 subtype: 'communication_preferences' 1596 } 1597 }, 1598 rayId 1599 ); 1600 }, 1601 pageVisit: () => { 1602 Tracker.sendPubSubEvent('PageVisit', { 1603 event: { 1604 type: 'page_visit' 1605 } 1606 }); 1607 }, 1608 productVisit: (e) => { 1609 const store = Tracker.translateTarget(e); 1610 const pageData = Tracker.store.get(store); 1611 const productData = Tracker.store.get('products')[pageData.sku]; 1612 Tracker.sendPubSubEvent( 1613 'ProductVisit', 1614 { 1615 event: { 1616 type: 'product_visit' 1617 }, 1618 page: { 1619 items: [ 1620 { 1621 product_group: { 1622 id: parseInt(productData?.item_id), 1623 selected_variant: { 1624 price: { 1625 currency: 1626 Tracker.store.get( 1627 'currency' 1628 ), 1629 value: parseFloat( 1630 productData?.price 1631 ) 1632 }, 1633 sku: parseInt(productData?.item_id) 1634 } 1635 } 1636 } 1637 ] 1638 } 1639 }, 1640 pageData.rayId 1641 ); 1642 }, 1643 // ---> MTA handlers <--- 1644 loginSuccess: ({ loginMethod, rayId, visitorId }) => { 1645 const elyEvent = { 1646 event: 'custom_event', 1647 event_name: 'login', 1648 method: loginMethod 1649 }; 1650 if (visitorId) { 1651 elyEvent.visitorId = visitorId; 1652 } 1653 Tracker.push(elyEvent); 1654 return Tracker.sendPubSubEvent( 1655 'Login', 1656 { 1657 event: { 1658 type: 'login', 1659 subtype: 'existing_customer' 1660 } 1661 }, 1662 rayId 1663 ); 1664 }, 1665 1666 loginFailed: ({ loginMethod, errorValue }) => { 1667 const elyEvent = { 1668 event: 'custom_event', 1669 event_name: 'login_failed', 1670 method: loginMethod, 1671 error_value: errorValue 1672 }; 1673 Tracker.push(elyEvent); 1674 }, 1675 1676 logout: () => { 1677 const elyEvent = { 1678 event: 'custom_event', 1679 event_name: 'logout' 1680 }; 1681 Tracker.push(elyEvent); 1682 }, 1683 1684 accountRegistrationSuccess: ({ 1685 registrationMethod, 1686 userId, 1687 rayId, 1688 visitorId, 1689 hashedEmail 1690 }) => { 1691 const elyEvent = { 1692 event: 'custom_event', 1693 event_name: 'sign_up', 1694 method: registrationMethod, 1695 user_id: userId, 1696 visitorEmailAddress: hashedEmail 1697 }; 1698 if (visitorId) { 1699 elyEvent.visitorId = visitorId; 1700 } 1701 Tracker.push(elyEvent); 1702 Tracker.sendPubSubEvent( 1703 'Login', 1704 { 1705 event: { 1706 type: 'login', 1707 subtype: 'account_creation' 1708 } 1709 }, 1710 rayId 1711 ); 1712 }, 1713 1714 accountRegistrationFail: ({ validationErrors }) => { 1715 const elyEvent = { 1716 event: 'custom_event', 1717 event_name: 'sign_up_failed', 1718 Validation_errors: validationErrors 1719 }; 1720 Tracker.push(elyEvent); 1721 }, 1722 1723 checkoutStart: async (e) => { 1724 const items = Tracker.store.get('checkout_start_items') || []; 1725 const currency = Tracker.store.get('currency'); 1726 1727 const gaEvent = { 1728 event_name: 'begin_checkout', 1729 currencyCode: currency, 1730 Items: items 1731 }; 1732 1733 Tracker.push(gaEvent); 1734 const store = Tracker.translateTarget(e); 1735 const data = Tracker.store.get(store); 1736 return Tracker.sendPubSubEvent( 1737 'StartCheckout', 1738 { 1739 event: { 1740 type: 'checkout_start',
1741 subtype: 'standard_checkout' 1742 } 1743 }, 1744 data.rayId 1745 ); 1746 }, 1747 guestCheckoutStart: async (e) => { 1748 const elyEvent = { 1749 event: 'elysiumEvent', 1750 event_name: 'continue_as_guest', 1751 category: 'Continue as guest', 1752 action: 'Clicked' 1753 }; 1754 Tracker.push(elyEvent); 1755 1756 const store = Tracker.translateTarget(e); 1757 const data = Tracker.store.get(store); 1758 return Tracker.sendPubSubEvent( 1759 'StartGuestCheckout', 1760 { 1761 event: { 1762 type: 'checkout_start', 1763 subtype: 'guest_checkout' 1764 } 1765 }, 1766 data.rayId 1767 ); 1768 }, 1769 // ---> MTA handlers <--- 1770 pageNotFound: () => { 1771 const gaEvent = { 1772 event: 'page_not_found' 1773 }; 1774 const elyEvent = { 1775 event: 'elysiumEvent', 1776 category: 'Errors', 1777 action: 'Page Not Found', 1778 path: window?.location?.pathname 1779 }; 1780 Tracker.push(gaEvent); 1781 Tracker.push(elyEvent); 1782 }, 1783 emptyList: (el) => { 1784 const gaEvent = { 1785 event: 'empty_page' 1786 }; 1787 const elyEvent = { 1788 event: 'elysiumEvent', 1789 label: 'Empty List', 1790 labelValue: el, 1791 path: window?.location?.pathname 1792 }; 1793 Tracker.push(gaEvent); 1794 Tracker.push(elyEvent); 1795 }, 1796 noSearchResult: (el) => { 1797 const gaEvent = { 1798 event: 'no_search_results', 1799 eventData: { 1800 input: el 1801 } 1802 }; 1803 const elyEvent = { 1804 event: 'elysiumEvent', 1805 label: 'No Search Results', 1806 labelValue: el, 1807 path: window?.location?.pathname + window?.location?.search 1808 }; 1809 Tracker.push(gaEvent); 1810 Tracker.push(elyEvent); 1811 }, 1812 startPageSize: (el) => { 1813 const key = Tracker.translateTarget(el); 1814 const size = Tracker.store.get(key); 1815 const gaEvent = { 1816 event: 'start_page_size', 1817 eventData: { 1818 height: size.height, 1819 width: size.width 1820 } 1821 }; 1822 const elyEvent = { 1823 event: 'elysiumEvent', 1824 label: 'Start Page Size', 1825 labelValue: { height: size.height, width: size.width }, 1826 path: window?.location?.pathname + window?.location?.search 1827 }; 1828 Tracker.push(gaEvent); 1829 Tracker.push(elyEvent); 1830 }, 1831 outOfStock: (el) => { 1832 const item = window.Tracker.store.get(el); 1833 const gaEvent = { 1834 event: 'sold_out_product', 1835 eventData: item 1836 }; 1837 const elyEvent = { 1838 event: 'elysiumEvent', 1839 label: 'Sold Out Product', 1840 labelValue: item, 1841 path: window?.location?.pathname + window?.location?.search 1842 }; 1843 Tracker.push(gaEvent); 1844 Tracker.push(elyEvent); 1845 } 1846 }, 1847 trackApiConfig: null, 1848 config: null, 1849 enabled: false, 1850 store: { 1851 get(k) { 1852 return Tracker.store[k]; 1853 }, 1854 set(k, v) { 1855 return (Tracker.store[k] = Tracker.store[k] 1856 ? Object.assign(Tracker.store[k], v) 1857 : v); 1858 } 1859 } 1860 }; 1861 Tracker.assignTracker(); 1862 if (typeof window.Tracker.load !== 'function') { 1863 Tracker.init({ 1864 debug: false, 1865 selectors: { 1866 track: 'data-track', 1867 type: 'data-track-type', 1868 store: 'data-track-push', 1869 currency: 'data-track-currency' 1870 } 1871 }); 1872 } else { 1873 window.Tracker.load(); 1874 } 1875})();
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.