PageSourceSearch

https://www.praxiscet.com/wp-content/plugins/praxis-klaviyo-core/assets/js/praxis-klaviyo-events.js?ver=1.0.7

js praxiscet.com collected 2026-09-24 12:13:08 UTC 5,944 bytes, 156 lines download raw bytes

1/**
2 * Client-side Klaviyo Event Tracking for Praxis
3 * Handles: Viewed Product, Started Checkout
4 */
5(function () {
6    'use strict';
7
8    // Ensure official Klaviyo onsite proxy and queue exists
9    !function(){if(!window.klaviyo||Array.isArray(window.klaviyo)){var e=Array.isArray(window.klaviyo)?window.klaviyo:[];window._klOnsite=window._klOnsite||[];for(var t=0;t<e.length;t++)window._klOnsite.push(e[t]);try{window.klaviyo=new Proxy({},{get:function(e,t){return"push"===t?function(){var e;(e=window._klOnsite).push.apply(e,arguments)}:function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];var o="function"==typeof n[n.length-1]?n.pop():void 0,i=new Promise(function(e){window._klOnsite.push([t].concat(n,[function(t){o&&o(t),e(t)}]))});return i}}})}catch(n){window.klaviyo=window.klaviyo||[],window.klaviyo.push=function(){var e;(e=window._klOnsite).push.apply(e,arguments)}}}}();
10
11    let data = window.praxisKlaviyoData || {};
12
13    let lastIdentifiedEmail = '';
14
15    /**
16     * Helper: Validate simple email format
17     */
18    function isValidEmail(email) {
19        return typeof email === 'string' && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim());
20    }
21
22    /**
23     * Identify an email with Klaviyo if valid and not already identified this pageview
24     */
25    function identifyEmail(email, source) {
26        let trimmed = (email || '').trim();
27        if (isValidEmail(trimmed) && trimmed.toLowerCase() !== lastIdentifiedEmail.toLowerCase()) {
28            lastIdentifiedEmail = trimmed;
29            window.klaviyo.identify({'$email': trimmed});
30        }
31    }
32
33    /**
34     * Helper to detect if an element is an email input
35     */
36    function isEmailInputElement(el) {
37        if (!el || el.tagName !== 'INPUT') {
38            return false;
39        }
40        let id = (el.id || '').toLowerCase();
41        let name = (el.name || '').toLowerCase();
42        let type = (el.type || '').toLowerCase();
43
44        return id === 'praxiscet-login-form__email' ||
45               id === 'edd-email' ||
46               name === 'edd_email' ||
47               type === 'email' ||
48               name.indexOf('email') !== -1 ||
49               id.indexOf('email') !== -1;
50    }
51
52    /**
53     * Set up listeners to auto-identify visitors when they type or submit their email
54     * Catches /checkout-login/ form (#praxiscet-login-form), EDD checkout inputs, etc.
55     */
56    function setupEmailIdentification() {
57        // Event delegation for input blur (focusout) and change across the entire document
58        document.addEventListener('focusout', function (e) {
59            if (isEmailInputElement(e.target)) {
60                identifyEmail(e.target.value, 'blur');
61            }
62        }, true);
63
64        document.addEventListener('change', function (e) {
65            if (isEmailInputElement(e.target)) {
66                identifyEmail(e.target.value, 'change');
67            }
68        }, true);
69
70        // Also listen for form submit (e.g. #praxiscet-login-form or checkout forms)
71        document.addEventListener('submit', function (e) {
72            let form = e.target;
73            if (!form || typeof form.querySelector !== 'function') {
74                return;
75            }
76
77            let emailInput = form.querySelector('#praxiscet-login-form__email, #edd-email, input[name="edd_email"], input[type="email"], input[name*="email"]');
78            if (emailInput && emailInput.value) {
79                identifyEmail(emailInput.value, 'submit');
80            }
81        }, true);
82    }
83
84    /**
85     * 1. Track "Viewed Product" on single course / event pages
86     */
87    function trackViewedProduct() {
88        if (!data.product || !data.product.id) {
89            return;
90        }
91
92        let prod = data.product;
93        let payload = {
94            "CourseTitle": prod.name || "",
95            "CourseCategories": Array.isArray(prod.categories) ? prod.categories : [],
96            "CourseID": String(prod.id),
97            "Type": prod.productType || "Live Training",
98            "URL": window.location.href
99        };
100
101        window.klaviyo.track('Viewed Product', payload);
102    }
103
104    /**
105     * 2. Track "Started Checkout" on the checkout page
106     * Flattened top-level properties so Klaviyo flow trigger filters work seamlessly.
107     */
108    function trackStartedCheckout() {
109        if (data.pageType !== 'checkout' || !data.cart || !Array.isArray(data.cart.items) || data.cart.items.length === 0) {
110            return;
111        }
112
113        let cart = data.cart;
114        let cartValue = typeof cart.value === 'number' ? cart.value : parseFloat(cart.value) || 0;
115        let firstItem = cart.items[0] || {};
116
117        let unixTime = Math.floor(Date.now() / 1000);
118        let cartId = cart.cartHash || (firstItem.id ? 'cart_' + firstItem.id : 'cart');
119        let eventId = cartId + '_' + unixTime;
120
121        let checkoutPayload = {
122            "$event_id": eventId,
123            "$value": cartValue,
124            "Currency": cart.currency || "USD",
125            "URL": cart.checkoutUrl || window.location.href,
126            "CourseTitle": firstItem.name || "",
127            "CourseCategories": Array.isArray(firstItem.categories) ? firstItem.categories : [],
128            "CourseID": String(firstItem.id || ""),
129            "Type": firstItem.productType || "On Demand"
130        };
131
132        window.klaviyo.track('Started Checkout', checkoutPayload);
133    }
134
135    // Initialize on DOM ready
136    function init() {
137        // Always activate email identification listeners (login, registration, checkout)
138        setupEmailIdentification();
139
140        if (data.pageType === 'checkout') {
141            trackStartedCheckout();
142            return;
143        }
144
145        if (data.product && data.product.id) {
146            trackViewedProduct();
147            return;
148        }
149    }
150
151    if (document.readyState === 'loading') {
152        document.addEventListener('DOMContentLoaded', init);
153    } else {
154        init();
155    }
156})();

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.