Skip to content
Notifications
Clear all

Trouble with the tracking pixel not firing on our SPA. Support wasn't helpful.

4 Posts
4 Users
0 Reactions
0 Views
(@ci_cd_junkie)
Estimable Member
Joined: 5 months ago
Posts: 134
Topic starter   [#17678]

Alright, so I've been wrestling with this for two days now and I'm hitting a wall. We're trying to integrate Gemini's tracking pixel into our Single Page Application (React-based, if that matters) and it's just... not firing consistently. Actually, it's worse than inconsistentβ€”it seems to fire on a full page reload but never on any client-side route transitions, which is kind of the whole point of an SPA, right? 😅

Our setup is pretty standard modern CI/CD fare: we build with Vite, run tests in GitHub Actions, and deploy to a cloud bucket. The pixel snippet from Gemini goes into our main `index.html` head, and in a traditional multi-page app, I'm sure it'd work fine. But in the SPA context, the script loads once and then seems to go dormant. Support basically told me to "ensure the pixel code is present on all pages," which shows a fundamental misunderstanding of how SPAs work. It *is* present, but the virtual page views aren't triggering it.

I've tried a few workarounds, and I'm curious if anyone else has been down this rabbit hole:

* **Pushing custom events to the data layer:** We have GTM set up for other things, so I tried firing a `historyChange` event and configuring a tag for the pixel. This feels clunky and I'm not even sure Gemini's pixel is built to listen for that.
* **Manually re-inserting the pixel script on navigation:** This is the nuclear option, and it feels wrong. Performance-wise, it's a non-starter.
* **Using the History API to trigger a re-evaluation:** I attempted to manually call whatever tracking function the injected script *should* expose, but digging through the minified blob, I can't find a clean hook.

Here's the exact pixel snippet we're given (with IDs changed, obviously):

```html

var _gfp = _gfp || [];
_gfp.push(['p', '123456']);
(function() {
var gfp = document.createElement('script'); gfp.type = 'text/javascript'; gfp.async = true;
gfp.src = ('https:' == document.location.protocol ? 'https:' : 'http:') + '//path.to.gemini.pixel/track.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(gfp, s);
})();


```

The core question I have for the community: **Is the Gemini tracking pixel fundamentally incompatible with modern SPAs without a significant workover?** Has anyone successfully gotten it to fire on every virtual pageview without a full reload? Did you have to proxy the requests through your own backend endpoint to control them, or did you find a frontend hack that works?

I'm considering writing a small service in our pipeline to inject a modified, SPA-aware version of the script during the build step, but that seems like a huge lift for basic analytics. Maybe there's a simpler solution staring me in the face.


pipeline all the things


   
Quote
(@ellej)
Trusted Member
Joined: 3 days ago
Posts: 29
 

Ah, the classic "just put it on every page" response from support for an SPA problem. A tale as old as time.

You're right that the pixel loads once and then sleeps through your route changes. The data layer/GTM route is the way most folks force it awake. Did you try firing the pixel's specific function directly on your router's `onRouteChange` event? Sometimes these pixels expose a manual trigger, like `window.geminiPixel.fire()`, which is more reliable than hoping GTM picks up a generic event.

If that doesn't exist, you might be stuck wrapping the pixel call in a new image request on each navigation - a bit clunky, but it often gets the job done when the vendor's JS is stubborn.



   
ReplyQuote
 ianb
(@ianb)
Trusted Member
Joined: 1 week ago
Posts: 52
 

Yep, that's exactly the wall you hit. The pixel's script runs on initial load, then considers its job done.

When you said you tried pushing custom events, did you check if the pixel's script actually created a global function you can call manually? Sometimes they leave a `window.__vendorTrack` or similar lying around, and you can call that directly in your router's useEffect instead of relying on GTM to listen and fire. It's a bit more surgical.

The other angle, which is a pain, is to treat each navigation like a fresh page load for the pixel's sake. You could manually create a new Image object and set its src to the tracking URL on each route change. It feels hacky, but it bypasses the vendor's dormant script entirely.


ian


   
ReplyQuote
(@charlie9)
Trusted Member
Joined: 6 days ago
Posts: 59
 

Exactly. The surgical approach only works if the vendor bothered to give you a scalpel. In my experience, half of these tracking scripts create a global function and the other half intentionally don't, to lock you into their "proper" integration path, which usually breaks in SPAs.

Even if you find that `window.__vendorTrack` function, you're now responsible for passing the correct payload on every route. Get one parameter wrong and the data is junk, but the vendor will still happily charge you for the "impression."


Show me the TCO.


   
ReplyQuote