@zaplier/sdk 1.6.9 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +373 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +18 -0
- package/dist/index.esm.js +373 -44
- package/dist/index.esm.js.map +1 -1
- package/dist/sdk.js +373 -44
- package/dist/sdk.js.map +1 -1
- package/dist/sdk.min.js +1 -1
- package/dist/src/modules/auto-tracker.d.ts +58 -3
- package/dist/src/modules/auto-tracker.d.ts.map +1 -1
- package/dist/src/modules/global-interface.d.ts +2 -0
- package/dist/src/modules/global-interface.d.ts.map +1 -1
- package/dist/src/sdk.d.ts +16 -0
- package/dist/src/sdk.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -932,9 +932,25 @@ declare class ZaplierSDK implements ZaplierSDK$1 {
|
|
|
932
932
|
trackHovers?: boolean;
|
|
933
933
|
trackForms?: boolean;
|
|
934
934
|
}) => void;
|
|
935
|
+
/**
|
|
936
|
+
* Refresh tracking for dynamic content (React/SPA route changes)
|
|
937
|
+
* Modern alternative to rescan() - follows GA4/industry best practices
|
|
938
|
+
*/
|
|
939
|
+
refreshTracking: () => void;
|
|
940
|
+
/**
|
|
941
|
+
* Legacy rescan method - use refreshTracking() instead
|
|
942
|
+
* @deprecated Use refreshTracking() for better performance
|
|
943
|
+
*/
|
|
944
|
+
rescan: () => void;
|
|
945
|
+
/**
|
|
946
|
+
* Get diagnostic information for debugging
|
|
947
|
+
*/
|
|
948
|
+
getDiagnostics: () => object | null;
|
|
935
949
|
getStats: () => {
|
|
936
950
|
observedElements: number;
|
|
937
951
|
config: AutoTrackerConfig;
|
|
952
|
+
isModern: boolean;
|
|
953
|
+
diagnostics?: object;
|
|
938
954
|
} | null;
|
|
939
955
|
isEnabled: () => boolean;
|
|
940
956
|
};
|
|
@@ -1119,6 +1135,8 @@ declare const Zaplier: {
|
|
|
1119
1135
|
getStats: () => {
|
|
1120
1136
|
observedElements: number;
|
|
1121
1137
|
config: AutoTrackerConfig;
|
|
1138
|
+
isModern: boolean;
|
|
1139
|
+
diagnostics?: object;
|
|
1122
1140
|
} | null;
|
|
1123
1141
|
isEnabled: () => boolean;
|
|
1124
1142
|
};
|
package/dist/index.esm.js
CHANGED
|
@@ -19262,6 +19262,8 @@ class AutoTracker {
|
|
|
19262
19262
|
constructor(sdkInstance, config = {}) {
|
|
19263
19263
|
this.observedElements = new Set();
|
|
19264
19264
|
this.scrollThrottle = 0;
|
|
19265
|
+
this.isInitialized = false;
|
|
19266
|
+
this.delegationHandlers = new Map();
|
|
19265
19267
|
this.handleScroll = () => {
|
|
19266
19268
|
if (!this.config.trackScrolls)
|
|
19267
19269
|
return;
|
|
@@ -19366,30 +19368,29 @@ class AutoTracker {
|
|
|
19366
19368
|
trackScrolls: this.config.trackScrolls,
|
|
19367
19369
|
trackViews: this.config.trackViews,
|
|
19368
19370
|
trackHovers: this.config.trackHovers,
|
|
19369
|
-
trackForms: this.config.trackForms
|
|
19371
|
+
trackForms: this.config.trackForms,
|
|
19372
|
+
domReady: document.readyState
|
|
19370
19373
|
});
|
|
19371
|
-
|
|
19372
|
-
|
|
19373
|
-
|
|
19374
|
-
|
|
19375
|
-
|
|
19376
|
-
|
|
19377
|
-
|
|
19378
|
-
|
|
19379
|
-
|
|
19380
|
-
scrollElements: scrollElements.length,
|
|
19381
|
-
viewElements: viewElements.length,
|
|
19382
|
-
hoverElements: hoverElements.length,
|
|
19383
|
-
formElements: formElements.length
|
|
19384
|
-
});
|
|
19385
|
-
if (scrollElements.length > 0) {
|
|
19386
|
-
console.log("[Zaplier AutoTracker] Elementos de scroll:", Array.from(scrollElements).map(el => ({
|
|
19387
|
-
tagName: el.tagName,
|
|
19388
|
-
trackEvent: el.getAttribute('data-track-scroll'),
|
|
19389
|
-
threshold: el.getAttribute('data-scroll-threshold') || '0.5'
|
|
19390
|
-
})));
|
|
19374
|
+
}
|
|
19375
|
+
// Aguardar DOM ready se necessário
|
|
19376
|
+
if (document.readyState === 'loading') {
|
|
19377
|
+
if (this.config.debug) {
|
|
19378
|
+
console.log("[Zaplier AutoTracker] DOM still loading, waiting for DOMContentLoaded...");
|
|
19379
|
+
}
|
|
19380
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
19381
|
+
if (this.config.debug) {
|
|
19382
|
+
console.log("[Zaplier AutoTracker] DOMContentLoaded fired, initializing tracking...");
|
|
19391
19383
|
}
|
|
19392
|
-
|
|
19384
|
+
this.initializeTracking();
|
|
19385
|
+
}, { once: true });
|
|
19386
|
+
}
|
|
19387
|
+
else {
|
|
19388
|
+
this.initializeTracking();
|
|
19389
|
+
}
|
|
19390
|
+
}
|
|
19391
|
+
initializeTracking() {
|
|
19392
|
+
if (this.config.debug) {
|
|
19393
|
+
console.log("[Zaplier AutoTracker] Initializing tracking...");
|
|
19393
19394
|
}
|
|
19394
19395
|
// Observer para novos elementos no DOM
|
|
19395
19396
|
this.observeDOM();
|
|
@@ -19399,42 +19400,269 @@ class AutoTracker {
|
|
|
19399
19400
|
if (this.config.trackViews) {
|
|
19400
19401
|
this.setupViewTracking();
|
|
19401
19402
|
}
|
|
19402
|
-
// Setup
|
|
19403
|
+
// Setup event delegation (modern approach)
|
|
19404
|
+
this.setupEventDelegation();
|
|
19405
|
+
// Debug: Log elementos encontrados após inicialização
|
|
19406
|
+
if (this.config.debug) {
|
|
19407
|
+
this.logFoundElements();
|
|
19408
|
+
// Também agendar uma verificação após delay para elementos React
|
|
19409
|
+
setTimeout(() => {
|
|
19410
|
+
console.log("[Zaplier AutoTracker] Re-checking elements after 500ms...");
|
|
19411
|
+
this.logFoundElements();
|
|
19412
|
+
}, 500);
|
|
19413
|
+
setTimeout(() => {
|
|
19414
|
+
console.log("[Zaplier AutoTracker] Re-checking elements after 2s...");
|
|
19415
|
+
this.logFoundElements();
|
|
19416
|
+
}, 2000);
|
|
19417
|
+
}
|
|
19418
|
+
}
|
|
19419
|
+
logFoundElements() {
|
|
19420
|
+
const clickElements = document.querySelectorAll('[data-track-click]');
|
|
19421
|
+
const scrollElements = document.querySelectorAll('[data-track-scroll]');
|
|
19422
|
+
const viewElements = document.querySelectorAll('[data-track-view]');
|
|
19423
|
+
const hoverElements = document.querySelectorAll('[data-track-hover]');
|
|
19424
|
+
const formElements = document.querySelectorAll('[data-track-form]');
|
|
19425
|
+
console.log("[Zaplier AutoTracker] Elementos encontrados:", {
|
|
19426
|
+
clickElements: clickElements.length,
|
|
19427
|
+
scrollElements: scrollElements.length,
|
|
19428
|
+
viewElements: viewElements.length,
|
|
19429
|
+
hoverElements: hoverElements.length,
|
|
19430
|
+
formElements: formElements.length,
|
|
19431
|
+
totalElements: clickElements.length + scrollElements.length + viewElements.length + hoverElements.length + formElements.length
|
|
19432
|
+
});
|
|
19433
|
+
if (scrollElements.length > 0) {
|
|
19434
|
+
console.log("[Zaplier AutoTracker] Elementos de scroll:", Array.from(scrollElements).map(el => ({
|
|
19435
|
+
tagName: el.tagName,
|
|
19436
|
+
trackEvent: el.getAttribute('data-track-scroll'),
|
|
19437
|
+
threshold: el.getAttribute('data-scroll-threshold') || '0.5',
|
|
19438
|
+
id: el.id || 'no-id',
|
|
19439
|
+
classes: el.className || 'no-classes'
|
|
19440
|
+
})));
|
|
19441
|
+
}
|
|
19442
|
+
}
|
|
19443
|
+
/**
|
|
19444
|
+
* Setup Event Delegation (Industry Best Practice)
|
|
19445
|
+
* Uses single document-level listeners instead of individual element listeners
|
|
19446
|
+
*/
|
|
19447
|
+
setupEventDelegation() {
|
|
19448
|
+
if (this.config.debug) {
|
|
19449
|
+
console.log("[AutoTracker] Setting up event delegation...");
|
|
19450
|
+
}
|
|
19451
|
+
// Click delegation
|
|
19403
19452
|
if (this.config.trackClicks) {
|
|
19404
|
-
|
|
19453
|
+
const clickHandler = this.createDelegatedClickHandler();
|
|
19454
|
+
this.delegationHandlers.set('click', clickHandler);
|
|
19455
|
+
document.addEventListener('click', clickHandler, { passive: true });
|
|
19405
19456
|
}
|
|
19457
|
+
// Scroll delegation (using global handler with element detection)
|
|
19406
19458
|
if (this.config.trackScrolls) {
|
|
19407
|
-
|
|
19459
|
+
const scrollHandler = this.createDelegatedScrollHandler();
|
|
19460
|
+
this.delegationHandlers.set('scroll', scrollHandler);
|
|
19461
|
+
document.addEventListener('scroll', scrollHandler, { passive: true });
|
|
19408
19462
|
}
|
|
19463
|
+
// Setup debounced mutation observer for dynamic content
|
|
19464
|
+
this.setupIntelligentMutationObserver();
|
|
19465
|
+
this.isInitialized = true;
|
|
19409
19466
|
}
|
|
19410
19467
|
/**
|
|
19411
|
-
*
|
|
19468
|
+
* Create delegated click handler (no individual listeners needed)
|
|
19412
19469
|
*/
|
|
19413
|
-
|
|
19414
|
-
|
|
19415
|
-
|
|
19416
|
-
|
|
19417
|
-
|
|
19470
|
+
createDelegatedClickHandler() {
|
|
19471
|
+
return (event) => {
|
|
19472
|
+
const target = event.target;
|
|
19473
|
+
if (!target || !this.config.trackClicks)
|
|
19474
|
+
return;
|
|
19475
|
+
// Check if target or any parent has data-track-click
|
|
19476
|
+
const trackingElement = target.closest('[data-track-click]');
|
|
19477
|
+
if (!trackingElement)
|
|
19478
|
+
return;
|
|
19479
|
+
const eventName = trackingElement.getAttribute('data-track-click');
|
|
19480
|
+
if (!eventName)
|
|
19481
|
+
return;
|
|
19482
|
+
const metadata = this.extractMetadata(trackingElement);
|
|
19483
|
+
this.trackEvent(eventName, {
|
|
19484
|
+
type: 'click',
|
|
19485
|
+
element: trackingElement.tagName.toLowerCase(),
|
|
19486
|
+
...metadata,
|
|
19487
|
+
});
|
|
19488
|
+
if (this.config.debug) {
|
|
19489
|
+
console.log(`[AutoTracker] Click tracked via delegation: ${eventName}`, {
|
|
19490
|
+
element: trackingElement.tagName.toLowerCase(),
|
|
19491
|
+
...metadata
|
|
19492
|
+
});
|
|
19493
|
+
}
|
|
19494
|
+
};
|
|
19495
|
+
}
|
|
19496
|
+
/**
|
|
19497
|
+
* Create delegated scroll handler (efficient global approach)
|
|
19498
|
+
*/
|
|
19499
|
+
createDelegatedScrollHandler() {
|
|
19500
|
+
return () => {
|
|
19501
|
+
if (!this.config.trackScrolls)
|
|
19502
|
+
return;
|
|
19503
|
+
// Throttle scroll events for performance
|
|
19504
|
+
const now = Date.now();
|
|
19505
|
+
if (now - this.scrollThrottle < 100)
|
|
19506
|
+
return;
|
|
19507
|
+
this.scrollThrottle = now;
|
|
19508
|
+
// Find all scroll tracking elements and check visibility
|
|
19509
|
+
const scrollElements = document.querySelectorAll('[data-track-scroll]');
|
|
19510
|
+
if (this.config.debug && scrollElements.length > 0) {
|
|
19511
|
+
console.log(`[AutoTracker] Checking ${scrollElements.length} scroll elements via delegation`);
|
|
19512
|
+
}
|
|
19513
|
+
scrollElements.forEach((element) => {
|
|
19514
|
+
this.processScrollElement(element);
|
|
19515
|
+
});
|
|
19516
|
+
};
|
|
19517
|
+
}
|
|
19518
|
+
/**
|
|
19519
|
+
* Process individual scroll element (extracted for reusability)
|
|
19520
|
+
*/
|
|
19521
|
+
processScrollElement(element) {
|
|
19522
|
+
const hasTriggered = element.getAttribute('data-scroll-triggered') === 'true';
|
|
19523
|
+
if (hasTriggered)
|
|
19524
|
+
return;
|
|
19525
|
+
const threshold = parseFloat(element.getAttribute('data-scroll-threshold') || '0.5');
|
|
19526
|
+
const rect = element.getBoundingClientRect();
|
|
19527
|
+
const elementHeight = rect.height;
|
|
19528
|
+
const visibleHeight = Math.min(rect.bottom, window.innerHeight) - Math.max(rect.top, 0);
|
|
19529
|
+
const visibilityRatio = Math.max(0, visibleHeight) / elementHeight;
|
|
19530
|
+
if (this.config.debug) {
|
|
19531
|
+
console.log(`[AutoTracker] Scroll element check via delegation:`, {
|
|
19532
|
+
elementId: element.id || element.className,
|
|
19533
|
+
visibilityRatio: Math.round(visibilityRatio * 100) / 100,
|
|
19534
|
+
threshold,
|
|
19535
|
+
triggered: hasTriggered
|
|
19536
|
+
});
|
|
19537
|
+
}
|
|
19538
|
+
if (visibilityRatio >= threshold) {
|
|
19539
|
+
element.setAttribute('data-scroll-triggered', 'true');
|
|
19540
|
+
const eventName = element.getAttribute('data-track-scroll');
|
|
19541
|
+
if (!eventName)
|
|
19542
|
+
return;
|
|
19543
|
+
const metadata = this.extractMetadata(element);
|
|
19544
|
+
this.trackEvent(eventName, {
|
|
19545
|
+
type: 'scroll',
|
|
19546
|
+
element: element.tagName.toLowerCase(),
|
|
19547
|
+
threshold,
|
|
19548
|
+
scrollDepth: window.scrollY,
|
|
19549
|
+
visibilityRatio: Math.round(visibilityRatio * 100) / 100,
|
|
19550
|
+
...metadata,
|
|
19551
|
+
});
|
|
19552
|
+
if (this.config.debug) {
|
|
19553
|
+
console.log(`[AutoTracker] Scroll tracked via delegation: ${eventName}`, {
|
|
19554
|
+
threshold,
|
|
19555
|
+
visibilityRatio,
|
|
19556
|
+
scrollDepth: window.scrollY,
|
|
19557
|
+
...metadata
|
|
19558
|
+
});
|
|
19559
|
+
}
|
|
19418
19560
|
}
|
|
19419
|
-
this.observedElements.clear();
|
|
19420
19561
|
}
|
|
19421
19562
|
/**
|
|
19422
|
-
*
|
|
19563
|
+
* Setup intelligent mutation observer (debounced for performance)
|
|
19423
19564
|
*/
|
|
19424
|
-
|
|
19425
|
-
|
|
19426
|
-
|
|
19427
|
-
|
|
19565
|
+
setupIntelligentMutationObserver() {
|
|
19566
|
+
if (this.mutationObserver)
|
|
19567
|
+
return; // Already setup
|
|
19568
|
+
const debouncedCallback = this.debounce((mutations) => {
|
|
19569
|
+
let hasRelevantChanges = false;
|
|
19570
|
+
mutations.forEach(mutation => {
|
|
19571
|
+
mutation.addedNodes.forEach(node => {
|
|
19428
19572
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
19429
|
-
|
|
19573
|
+
const element = node;
|
|
19574
|
+
if (this.hasTrackingAttributes(element) || this.hasTrackingDescendants(element)) {
|
|
19575
|
+
hasRelevantChanges = true;
|
|
19576
|
+
if (this.config.debug) {
|
|
19577
|
+
console.log('[AutoTracker] New trackable element detected via mutation observer:', element);
|
|
19578
|
+
}
|
|
19579
|
+
}
|
|
19430
19580
|
}
|
|
19431
19581
|
});
|
|
19432
19582
|
});
|
|
19433
|
-
|
|
19434
|
-
|
|
19583
|
+
if (hasRelevantChanges) {
|
|
19584
|
+
if (this.config.debug) {
|
|
19585
|
+
console.log('[AutoTracker] Processing new elements from mutations...');
|
|
19586
|
+
}
|
|
19587
|
+
// Process elements for view tracking (only thing that needs setup)
|
|
19588
|
+
this.processExistingElements();
|
|
19589
|
+
}
|
|
19590
|
+
}, 150);
|
|
19591
|
+
this.mutationObserver = new MutationObserver(debouncedCallback);
|
|
19592
|
+
this.mutationObserver.observe(document.body, {
|
|
19435
19593
|
childList: true,
|
|
19436
19594
|
subtree: true,
|
|
19437
19595
|
});
|
|
19596
|
+
if (this.config.debug) {
|
|
19597
|
+
console.log('[AutoTracker] Intelligent mutation observer setup complete');
|
|
19598
|
+
}
|
|
19599
|
+
}
|
|
19600
|
+
/**
|
|
19601
|
+
* Check if element has tracking attributes
|
|
19602
|
+
*/
|
|
19603
|
+
hasTrackingAttributes(element) {
|
|
19604
|
+
return element.hasAttribute && (element.hasAttribute('data-track-click') ||
|
|
19605
|
+
element.hasAttribute('data-track-scroll') ||
|
|
19606
|
+
element.hasAttribute('data-track-view') ||
|
|
19607
|
+
element.hasAttribute('data-track-hover') ||
|
|
19608
|
+
element.hasAttribute('data-track-form'));
|
|
19609
|
+
}
|
|
19610
|
+
/**
|
|
19611
|
+
* Check if element has tracking descendants
|
|
19612
|
+
*/
|
|
19613
|
+
hasTrackingDescendants(element) {
|
|
19614
|
+
if (!element.querySelector)
|
|
19615
|
+
return false;
|
|
19616
|
+
return !!(element.querySelector('[data-track-click]') ||
|
|
19617
|
+
element.querySelector('[data-track-scroll]') ||
|
|
19618
|
+
element.querySelector('[data-track-view]') ||
|
|
19619
|
+
element.querySelector('[data-track-hover]') ||
|
|
19620
|
+
element.querySelector('[data-track-form]'));
|
|
19621
|
+
}
|
|
19622
|
+
/**
|
|
19623
|
+
* Utility: Debounce function for performance optimization
|
|
19624
|
+
*/
|
|
19625
|
+
debounce(func, wait) {
|
|
19626
|
+
let timeout;
|
|
19627
|
+
return (...args) => {
|
|
19628
|
+
clearTimeout(timeout);
|
|
19629
|
+
timeout = setTimeout(() => func.apply(this, args), wait);
|
|
19630
|
+
};
|
|
19631
|
+
}
|
|
19632
|
+
/**
|
|
19633
|
+
* Parar auto tracking (with proper cleanup)
|
|
19634
|
+
*/
|
|
19635
|
+
stop() {
|
|
19636
|
+
if (this.config.debug) {
|
|
19637
|
+
console.log('[AutoTracker] Stopping auto tracking and cleaning up...');
|
|
19638
|
+
}
|
|
19639
|
+
// Remove delegation handlers
|
|
19640
|
+
this.delegationHandlers.forEach((handler, eventType) => {
|
|
19641
|
+
document.removeEventListener(eventType, handler);
|
|
19642
|
+
});
|
|
19643
|
+
this.delegationHandlers.clear();
|
|
19644
|
+
// Disconnect observers
|
|
19645
|
+
if (this.intersectionObserver) {
|
|
19646
|
+
this.intersectionObserver.disconnect();
|
|
19647
|
+
this.intersectionObserver = undefined;
|
|
19648
|
+
}
|
|
19649
|
+
if (this.mutationObserver) {
|
|
19650
|
+
this.mutationObserver.disconnect();
|
|
19651
|
+
this.mutationObserver = undefined;
|
|
19652
|
+
}
|
|
19653
|
+
// Clear caches
|
|
19654
|
+
this.observedElements.clear();
|
|
19655
|
+
this.isInitialized = false;
|
|
19656
|
+
}
|
|
19657
|
+
/**
|
|
19658
|
+
* Legacy method - now handled by intelligent mutation observer
|
|
19659
|
+
* @deprecated Use setupIntelligentMutationObserver instead
|
|
19660
|
+
*/
|
|
19661
|
+
observeDOM() {
|
|
19662
|
+
// This is now handled by setupIntelligentMutationObserver in setupEventDelegation
|
|
19663
|
+
if (this.config.debug) {
|
|
19664
|
+
console.log('[AutoTracker] observeDOM() is deprecated - using intelligent mutation observer');
|
|
19665
|
+
}
|
|
19438
19666
|
}
|
|
19439
19667
|
/**
|
|
19440
19668
|
* Processar elementos já existentes no DOM
|
|
@@ -19622,15 +19850,35 @@ class AutoTracker {
|
|
|
19622
19850
|
* Enviar evento para o SDK
|
|
19623
19851
|
*/
|
|
19624
19852
|
trackEvent(eventName, metadata) {
|
|
19625
|
-
if (
|
|
19853
|
+
if (this.config.debug) {
|
|
19854
|
+
console.log("[AutoTracker] trackEvent called:", { eventName, metadata });
|
|
19855
|
+
}
|
|
19856
|
+
if (!this.sdkInstance) {
|
|
19857
|
+
if (this.config.debug) {
|
|
19858
|
+
console.error("[AutoTracker] SDK instance is null!");
|
|
19859
|
+
}
|
|
19860
|
+
return;
|
|
19861
|
+
}
|
|
19862
|
+
if (typeof this.sdkInstance.trackCustomEvent !== 'function') {
|
|
19863
|
+
if (this.config.debug) {
|
|
19864
|
+
console.error("[AutoTracker] trackCustomEvent is not a function:", typeof this.sdkInstance.trackCustomEvent);
|
|
19865
|
+
}
|
|
19626
19866
|
return;
|
|
19867
|
+
}
|
|
19627
19868
|
try {
|
|
19628
|
-
|
|
19869
|
+
const eventData = {
|
|
19629
19870
|
autoTracked: true,
|
|
19630
19871
|
timestamp: Date.now(),
|
|
19631
19872
|
url: window.location.href,
|
|
19632
19873
|
...metadata,
|
|
19633
|
-
}
|
|
19874
|
+
};
|
|
19875
|
+
if (this.config.debug) {
|
|
19876
|
+
console.log("[AutoTracker] Calling trackCustomEvent:", { eventName, eventData });
|
|
19877
|
+
}
|
|
19878
|
+
const result = this.sdkInstance.trackCustomEvent(eventName, eventData);
|
|
19879
|
+
if (this.config.debug) {
|
|
19880
|
+
console.log("[AutoTracker] trackCustomEvent result:", result);
|
|
19881
|
+
}
|
|
19634
19882
|
}
|
|
19635
19883
|
catch (error) {
|
|
19636
19884
|
if (this.config.debug) {
|
|
@@ -19638,6 +19886,55 @@ class AutoTracker {
|
|
|
19638
19886
|
}
|
|
19639
19887
|
}
|
|
19640
19888
|
}
|
|
19889
|
+
/**
|
|
19890
|
+
* Modern API: Refresh tracking for dynamic content (React/SPA support)
|
|
19891
|
+
* Industry best practice for SPA route changes
|
|
19892
|
+
*/
|
|
19893
|
+
refreshTracking() {
|
|
19894
|
+
if (!this.isInitialized) {
|
|
19895
|
+
if (this.config.debug) {
|
|
19896
|
+
console.log('[AutoTracker] Not initialized, cannot refresh tracking');
|
|
19897
|
+
}
|
|
19898
|
+
return;
|
|
19899
|
+
}
|
|
19900
|
+
if (this.config.debug) {
|
|
19901
|
+
console.log('[AutoTracker] Refreshing tracking for dynamic content...');
|
|
19902
|
+
}
|
|
19903
|
+
// Re-process elements for view tracking (only thing that needs setup)
|
|
19904
|
+
this.processExistingElements();
|
|
19905
|
+
// Log current state
|
|
19906
|
+
if (this.config.debug) {
|
|
19907
|
+
this.logFoundElements();
|
|
19908
|
+
}
|
|
19909
|
+
}
|
|
19910
|
+
/**
|
|
19911
|
+
* Legacy method - use refreshTracking() instead
|
|
19912
|
+
* @deprecated Use refreshTracking() for better performance
|
|
19913
|
+
*/
|
|
19914
|
+
rescan() {
|
|
19915
|
+
this.refreshTracking();
|
|
19916
|
+
}
|
|
19917
|
+
/**
|
|
19918
|
+
* Get diagnostic information for debugging
|
|
19919
|
+
*/
|
|
19920
|
+
getDiagnostics() {
|
|
19921
|
+
return {
|
|
19922
|
+
isInitialized: this.isInitialized,
|
|
19923
|
+
hasClickHandler: this.delegationHandlers.has('click'),
|
|
19924
|
+
hasScrollHandler: this.delegationHandlers.has('scroll'),
|
|
19925
|
+
observedElements: this.observedElements.size,
|
|
19926
|
+
hasMutationObserver: !!this.mutationObserver,
|
|
19927
|
+
hasIntersectionObserver: !!this.intersectionObserver,
|
|
19928
|
+
config: this.config,
|
|
19929
|
+
elementsFound: {
|
|
19930
|
+
click: document.querySelectorAll('[data-track-click]').length,
|
|
19931
|
+
scroll: document.querySelectorAll('[data-track-scroll]').length,
|
|
19932
|
+
view: document.querySelectorAll('[data-track-view]').length,
|
|
19933
|
+
hover: document.querySelectorAll('[data-track-hover]').length,
|
|
19934
|
+
form: document.querySelectorAll('[data-track-form]').length
|
|
19935
|
+
}
|
|
19936
|
+
};
|
|
19937
|
+
}
|
|
19641
19938
|
/**
|
|
19642
19939
|
* Configurar tracking
|
|
19643
19940
|
*/
|
|
@@ -19645,12 +19942,14 @@ class AutoTracker {
|
|
|
19645
19942
|
this.config = { ...this.config, ...config };
|
|
19646
19943
|
}
|
|
19647
19944
|
/**
|
|
19648
|
-
*
|
|
19945
|
+
* Enhanced stats with diagnostic information
|
|
19649
19946
|
*/
|
|
19650
19947
|
getStats() {
|
|
19651
19948
|
return {
|
|
19652
19949
|
observedElements: this.observedElements.size,
|
|
19653
19950
|
config: this.config,
|
|
19951
|
+
isModern: this.isInitialized, // Indicates if using new delegation system
|
|
19952
|
+
diagnostics: this.config.debug ? this.getDiagnostics() : undefined
|
|
19654
19953
|
};
|
|
19655
19954
|
}
|
|
19656
19955
|
}
|
|
@@ -20199,6 +20498,36 @@ class ZaplierSDK {
|
|
|
20199
20498
|
console.log("[Zaplier] Auto tracking configured:", config);
|
|
20200
20499
|
}
|
|
20201
20500
|
},
|
|
20501
|
+
/**
|
|
20502
|
+
* Refresh tracking for dynamic content (React/SPA route changes)
|
|
20503
|
+
* Modern alternative to rescan() - follows GA4/industry best practices
|
|
20504
|
+
*/
|
|
20505
|
+
refreshTracking: () => {
|
|
20506
|
+
if (this.autoTracker) {
|
|
20507
|
+
this.autoTracker.refreshTracking();
|
|
20508
|
+
}
|
|
20509
|
+
if (this.config.debug) {
|
|
20510
|
+
console.log("[Zaplier] Auto tracking refreshed");
|
|
20511
|
+
}
|
|
20512
|
+
},
|
|
20513
|
+
/**
|
|
20514
|
+
* Legacy rescan method - use refreshTracking() instead
|
|
20515
|
+
* @deprecated Use refreshTracking() for better performance
|
|
20516
|
+
*/
|
|
20517
|
+
rescan: () => {
|
|
20518
|
+
if (this.autoTracker) {
|
|
20519
|
+
this.autoTracker.rescan();
|
|
20520
|
+
}
|
|
20521
|
+
if (this.config.debug) {
|
|
20522
|
+
console.log("[Zaplier] Auto tracking rescanned (deprecated - use refreshTracking)");
|
|
20523
|
+
}
|
|
20524
|
+
},
|
|
20525
|
+
/**
|
|
20526
|
+
* Get diagnostic information for debugging
|
|
20527
|
+
*/
|
|
20528
|
+
getDiagnostics: () => {
|
|
20529
|
+
return this.autoTracker ? this.autoTracker.getDiagnostics() : null;
|
|
20530
|
+
},
|
|
20202
20531
|
getStats: () => {
|
|
20203
20532
|
return this.autoTracker ? this.autoTracker.getStats() : null;
|
|
20204
20533
|
},
|