We enabled Predictive Engagement on our customer portal to trigger proactive chat offers based on browsing behavior. The journey mapping is configured and the action map rules are set up to offer chat after a visitor views 3 or more product pages within a session.
The problem is that Predictive Engagement is registering 2-3 page view events for every single page load. A customer who visits one product page is immediately getting a chat offer because the system thinks they have visited 3 pages.
I looked at the web tracking events in the Journey > Event Timeline view, and I can see duplicate pageview events with timestamps 50-200 milliseconds apart for the same URL. The visitor session is correct (single session ID), but the event count is inflated.
Our portal is a React single-page application. We are using the Genesys Predictive Engagement tracking snippet version 2.1.0 injected via Google Tag Manager. The snippet is placed in the GTM container and fires on the “All Pages” trigger.
Is there a known issue with the tracking snippet firing multiple times in SPA environments?
Yeah this is a classic SPA problem with the PE tracking snippet. The issue is your GTM “All Pages” trigger.
In a traditional multi-page site, “All Pages” fires once per full page load. But in a React SPA, the GTM dataLayer receives a gtm.historyChange event every time React Router changes the URL. If your GTM trigger is set to fire on both gtm.js (page load) AND gtm.historyChange, the tracking snippet initializes twice per navigation.
The fix is to change your GTM trigger from “All Pages” to a custom trigger that only fires on gtm.js (the initial page load). Then handle subsequent SPA route changes by calling the Predictive Engagement JavaScript SDK method directly from your React router:
// In your React Router onChange handler
Genesys('command', 'journey.pageview', {
pageTitle: document.title,
pageLocation: window.location.href
});
This gives you explicit control over when pageview events fire and eliminates the duplicates entirely.
The GTM trigger fix is the right answer. One additional thing to check - if you are also running Google Analytics 4 (GA4) with enhanced measurement enabled, GA4 injects its own history.pushState listener that can trigger additional GTM dataLayer pushes.
We had a case where even after fixing the PE trigger, we were still getting duplicate events because GA4 enhanced measurement was firing page_view events on every hash change. The PE snippet was picking those up as separate pageviews.
To verify, open Chrome DevTools > Console and run dataLayer.filter(e => e.event === 'gtm.historyChange') after navigating to a single page. If you see more than one entry per navigation, you have a duplicate event source.
The cleanest architecture is to disable the GTM-based PE snippet entirely and load it directly in your React app as an npm package using @genesys/purecloud-streaming-client, which gives you full lifecycle control.