|
716 | 716 | return false; |
717 | 717 | } |
718 | 718 |
|
| 719 | + // More reliable bot detection that doesn't flag mobile browsers |
719 | 720 | return ( |
720 | 721 | navigator.webdriver || |
721 | | - !navigator.plugins.length || |
722 | | - !navigator.languages.length |
| 722 | + // Remove plugins check - mobile browsers legitimately have 0 plugins |
| 723 | + !navigator.languages.length || |
| 724 | + // Additional bot indicators |
| 725 | + navigator.userAgent.includes('HeadlessChrome') || |
| 726 | + navigator.userAgent.includes('PhantomJS') || |
| 727 | + window.callPhantom || |
| 728 | + window._phantom || |
| 729 | + // Check for automation frameworks |
| 730 | + window.selenium || |
| 731 | + window.webdriver || |
| 732 | + document.documentElement.getAttribute('webdriver') === 'true' |
723 | 733 | ); |
724 | 734 | } |
725 | 735 |
|
|
728 | 738 | return; |
729 | 739 | } |
730 | 740 |
|
731 | | - for (const event of ['mousemove', 'scroll', 'keydown']) { |
| 741 | + const interactionEvents = [ |
| 742 | + 'mousemove', |
| 743 | + 'scroll', |
| 744 | + 'keydown', |
| 745 | + 'touchstart', |
| 746 | + 'touchmove', |
| 747 | + 'click', |
| 748 | + ]; |
| 749 | + |
| 750 | + for (const event of interactionEvents) { |
732 | 751 | window.addEventListener( |
733 | 752 | event, |
734 | 753 | () => { |
735 | 754 | this.hasInteracted = true; |
| 755 | + // Debug mobile interaction detection |
| 756 | + if (event.startsWith('touch') && this.options.debug) { |
| 757 | + console.log(`Databuddy: Mobile interaction detected (${event})`); |
| 758 | + } |
736 | 759 | }, |
737 | 760 | { once: true, passive: true } |
738 | 761 | ); |
|
807 | 830 | return; |
808 | 831 | } |
809 | 832 |
|
| 833 | + // Add bot detection check to match screen_view behavior |
| 834 | + if (this.options.disabled || this.isLikelyBot) { |
| 835 | + return; |
| 836 | + } |
| 837 | + |
810 | 838 | const baseContext = this.getBaseContext(); |
811 | 839 |
|
812 | 840 | const exitEventId = `exit_${this.sessionId}_${btoa(window.location.pathname)}_${this.pageEngagementStart}`; |
|
833 | 861 | interaction_count, |
834 | 862 | has_exit_intent: this.hasExitIntent, |
835 | 863 | page_count, |
836 | | - is_bounce: page_count <= 1 ? 1 : 0, |
837 | 864 | }, |
838 | 865 | }; |
839 | 866 |
|
|
842 | 869 |
|
843 | 870 | async sendExitEventImmediately(exitEvent) { |
844 | 871 | try { |
845 | | - const beaconResult = await this.sendBeacon(exitEvent); |
846 | | - if (beaconResult) { |
847 | | - return beaconResult; |
| 872 | + if (navigator.sendBeacon) { |
| 873 | + const beaconResult = await this.sendBeacon(exitEvent); |
| 874 | + if (beaconResult) { |
| 875 | + return beaconResult; |
| 876 | + } |
848 | 877 | } |
849 | 878 |
|
850 | 879 | return this.api.fetch('/', exitEvent, { |
851 | 880 | keepalive: true, |
852 | 881 | }); |
853 | 882 | } catch (_e) { |
| 883 | + try { |
| 884 | + if (navigator.sendBeacon) { |
| 885 | + return this.sendBeacon(exitEvent); |
| 886 | + } |
| 887 | + } catch (_e2) { |
| 888 | + // Silent fail - don't block page unload |
| 889 | + } |
854 | 890 | return null; |
855 | 891 | } |
856 | 892 | } |
|
1230 | 1266 |
|
1231 | 1267 | if (this.options.trackScreenViews) { |
1232 | 1268 | this.trackScreenViews(); |
1233 | | - setTimeout(() => this.screenView(), 0); |
| 1269 | + // Delay initial screen view to ensure proper mobile initialization |
| 1270 | + setTimeout(() => this.screenView(), 100); |
1234 | 1271 | } |
1235 | 1272 |
|
1236 | 1273 | if (this.options.trackOutgoingLinks) { |
|
1310 | 1347 | }); |
1311 | 1348 | this.isInternalNavigation = true; |
1312 | 1349 | this.screenView(); |
1313 | | - }, 50); |
| 1350 | + }, 100); // Increase debounce for mobile stability |
1314 | 1351 |
|
1315 | 1352 | this.options.trackHashChanges |
1316 | 1353 | ? window.addEventListener('hashchange', i) |
|
0 commit comments