Fixing Affiliate Tracking Tools When They Gaslight You
Affiliate link redirects that quietly clip referrers
This one drove me nuts for about two weeks. A new browser extension I installed — ironically to track click-throughs more easily — was eating the Referer
header on some outbound affiliate links. No warning. No console error. Just lower conversion reports and some vague complaints from a partner platform rep.
If you have redirects that chain domains (e.g., yoursite.com → go.aff.biz → partner.com
), make sure your intermediate domains decay gracefully. If any of those hits a 301+301 or injects a meta refresh
, you can lose referrer context. Some affiliate platforms like CJ or ShareASale will still attribute the click, but you might lose parameter data, especially if the redirect creates a blank document load.
“It was working until we moved the shortlink domain onto Cloudflare Pages.” — actually me, realizing static hosting breaks server-side meta tags.
Use document.referrer
in a console after redirect to verify. Spoiler: Chrome now strips it unexpectedly when cross-origin via HTTPS+nofollow unless you manually set redirect headers to allow full referrer policies. Firefox is slightly more lenient, but this stuff gets dark fast.
Tracking scripts colliding in the iframe underworld
Affiliate networks love hiding tracking pixels in invisible iframes, usually for cookie setting. But if your page also loads GTM or other pixel-heavy marketing scripts, timing becomes hellish. I had a setup on a merch site where the Amazon affiliate pixel fired — but was regularly stifled by an analytics heatmap tool that injected a DOM observer. Never showed up in the network tab because it got pre-empted before DOMContentLoaded.
My fix (that shouldn’t have worked):
<iframe style="display:none" src="//affiliate.com/pixel?subid=..." sandbox="allow-scripts"></iframe>
For some reason, giving the iframe a sandbox
with allow-scripts
but not allow-same-origin
made it fire more reliably across Firefox and Chromium. Likely because third-party content script injectors bailed on sandboxed iframes. This is not documented anywhere obvious, just trial and error over too many lattes.
Platforms that pretend UTM parameters don’t exist
Rakuten and Impact both have edge caches that sometimes 302 UTM parameters out of existence. This mostly happens on mobile Safari, where the affiliate link looks like it worked, gets rewritten or stripped, and the session logs no origin unless their JS snippet loads in time. It doesn’t, half the time.
I realized this when I tried logging raw inbound location.href
to a server endpoint — the UTM keys were just… not there. But add a 50ms delay via setTimeout before redirecting users to the outbound destination, and boom: parameters captured. Not ideal UX-wise, but functionally saved hundreds of misattributed clicks.
Honestly, the best tip here is:
- Use server-side redirects with querystring preservation
- Avoid shorteners that cloak originals if you care about attribution (Bitly with branded domains is actually worse at this)
- If you’re losing parameters, check CDN cache policies for querystring stripping
- Watch out for mobile Facebook or Instagram in-app browsers — Safari ViewController wrecks referrers
The Massdrop fiasco two years back was essentially this — over half their referral traffic got misbinned as direct due to careless redirects.
The Google Analytics total lie about affiliate funnel completion
GA4 conversion tracking doesn’t like multi-session flows, especially when there’s an outbound affiliate jump mid-funnel. You can’t always stitch session1 (click → affiliate) to session2 (signup → email → conversion) unless you’re doing heavy-duty cookie syncing. Some platforms retrocredit via the affiliate ID query param, but GA4 just sees another source.
Before, we faked it by grabbing gclid
and stuffing it into localStorage, then replaying it on the return load. Worked until Google decided some cross-origin setups were “non-consensual” and nuked our attribution model. Now we run a faux interstitial screen where we sync data before pushing outbound — basically a 2-second delay page that logs session cookies to a tiny Go endpoint. Surprisingly, affiliate sales reporting went up the week we added that.
When CJ Affiliate’s deep link builder breaks silently
There’s a form tool in CJ’s dashboard that builds deep links to product pages. It used to append a valid PID automatically but sometime late last year (no changelog, no email), they started omitting the &pid=
value if the browser was in incognito. No alert, just malformed links.
I only noticed this because someone else in my team was copy/pasting from private mode, trying to QA unrelated tracking. The kicker is: if you manually visit CJ’s dashboard in incognito, it loads without some JavaScript conditionals so half the fields are not prepopulated. Their support response? “Try using standard mode for publisher tools.” Classic.
So log your generated URLs somewhere — even if just dumping them into Slack — and test a few live every week. Trusting auto-builders gets dangerous when browser privacy settings mess with form behavior you didn’t expect to be stateful.
Checkboxed opt-in systems that nuke affiliate cookies
Remember when we all rushed to slap cookie consent modals everywhere? Turns out, some modal vendors — looking at you, older OneTrust widgets — stopped affiliate cookies dead unless users clicked Accept All. This meant affiliate clicks were valid, cookies were returned, but got blocked by JS-installed consent gates.
If you’re doing cookie-based attribution, those opt-in checkboxes must fire AFTER setting session-level info server-side. Otherwise you’re doing the digital version of handing out flyers in a wind tunnel.
“That’s weird, we have high bounce rate and zero clickthrough conversions… oh.” — a data guy, twenty cups deep into a dead campaign
Merge conflicts that quietly overwrite affiliate IDs
This one’s a personal embarrassment. We had a site doing dynamic outbound link generation using backend route params. After a minor merge, someone else pushed logic that stripped out affId
from the render method if it wasn’t explicitly passed in config. But our affiliate IDs were stored higher up in a layout loader, not inline.
So yeah: no build errors, no linter complaints, just thousands of links defaulting to ?affId=undefined
. For a week. No tracking, no revenue, no notification.
This is why I now keep a dirty little stub script that crawls rendered outbound links once a day and logs mismatches against a local ID map. It’s dumb. Super dumb. But until someone builds a CI that tracks raw link deltas, that’s my lifeline.
Cloudflare’s rocket loader can break affiliate script order
Cloudflare’s Rocket Loader is supposed to optimize JS by deferring non-critical scripts. What it actually does sometimes is: reorders script tags in ways that affiliate tracking scripts don’t expect. One time it loaded the affiliate merchant script before the session cookie script, so affiliate cookies were never written — making every sale look like an untracked origin purchase.
I finally figured it out because I noticed it only affected product detail pages, and only in Chrome. For some reason Rocket Loader gets especially aggressive when it sees a bunch of async scripts, and if the affiliate pixel doesn’t explicitly wait on document-ready, it’s toast.
Fix? On pages where you care about tracking, add data-cfasync="false"
to affiliate scripts, even inline ones. It tells Cloudflare: hands off, don’t mess with this script’s execution order. More importantly, test your conversion attribution after enabling Rocket Loader — measure, don’t trust.
“I don’t have time to test all that.” Great. Enjoy your zero-dollar week.