-
Notifications
You must be signed in to change notification settings - Fork 55
Description
Expected Behavior
When using the excludeReferrers configuration option in the Web Attribution Plugin, it should:
- Exclude the specified referrer domains from being tracked in the
referrerandreferring_domainattribution fields - Continue to track UTM parameters and click IDs (gclid, fbclid, etc.) when they are present in the URL, regardless of the referrer
The intent of excludeReferrers should be to prevent self-referrals from your own domain from creating false attribution, while still capturing legitimate campaign parameters that exist in the URL.
Current Behavior
When a referrer matches an excludeReferrers pattern, the plugin completely blocks ALL campaign parameter tracking, including:
- UTM parameters (utm_source, utm_medium, utm_campaign, etc.)
- Click IDs (gclid, fbclid, etc.)
- All other campaign attribution data
This results in missing attribution data even when valid campaign parameters are present in the URL.
Possible Solution
The bug is in @amplitude/analytics-client-common/lib/esm/attribution/helpers.js in the isNewCampaign() function (lines 19-23):
if (isExcludedReferrer(options.excludeReferrers, current.referring_domain)) {
logger.debug("This is not a new campaign because ".concat(current.referring_domain, " is in the exclude referrer list."));
return false; // ← BUG: Returns false immediately, blocking ALL campaign tracking
}The excludeReferrers check happens before checking if there are actual new campaign parameters (line 29). This causes the function to return false immediately, preventing any attribution tracking.
Suggested Fix:
The excludeReferrers check should only affect the hasNewDomain calculation, not the entire isNewCampaign result. Campaign parameters should still be tracked even when the referrer is excluded. For example:
export var isNewCampaign = function (current, previous, options, logger, isNewSession) {
// ... existing setup code ...
var hasNewCampaign = JSON.stringify(currentCampaign) !== JSON.stringify(previousCampaign);
// Only apply excludeReferrers to domain-based attribution, not parameter-based attribution
var isReferrerExcluded = isExcludedReferrer(options.excludeReferrers, current.referring_domain);
var hasNewDomain = !isReferrerExcluded &&
domainWithoutSubdomain(referring_domain || '') !== domainWithoutSubdomain(prevReferringDomain || '');
// If referrer is excluded, log it but still check for campaign parameter changes
if (isReferrerExcluded) {
logger.debug("Referrer " + current.referring_domain + " is excluded, but checking for campaign parameter changes.");
}
var result = !previous || hasNewCampaign || hasNewDomain;
// ... rest of function
}Steps to Reproduce
- Configure the Web Attribution Plugin with
excludeReferrersto exclude your own domain:
import { webAttributionPlugin } from '@amplitude/plugin-web-attribution-browser';
const webAttribution = webAttributionPlugin({
excludeReferrers: [/yourdomain\.com$/]
});
amplitude.add(webAttribution);
await amplitude.init('YOUR_API_KEY');-
User lands on your site from a Google Ad with campaign parameters:
- URL:
https://yourdomain.com/?utm_source=google&utm_medium=cpc&gclid=123 document.referrer:https://www.google.com- Result: Attribution tracked correctly ✅
- URL:
-
User navigates to another page internally:
- URL:
https://yourdomain.com/other-page?utm_source=google&utm_medium=cpc&gclid=123(parameters preserved) document.referrer:https://yourdomain.com(matches excludeReferrers pattern)- Expected: UTM parameters and gclid should still be tracked
- Actual: No attribution tracking happens at all ❌
- URL:
-
Check Amplitude events - you'll see the campaign parameters are missing from the internal navigation events, even though they were in the URL.
Additional Scenario: Server-Side Redirects
This bug is particularly problematic when using server-side redirects (e.g., Next.js redirects in next.config.js):
- User clicks Google Ad landing on:
https://yourdomain.com/pricing?utm_source=google&utm_medium=cpc&gclid=123 - Server performs redirect (with query parameters preserved):
https://yourdomain.com/product/pricing?utm_source=google&utm_medium=cpc&gclid=123 - After redirect:
document.referrer:https://yourdomain.com/pricing(the pre-redirect URL on your own domain)- Current URL:
https://yourdomain.com/product/pricing?utm_source=google&utm_medium=cpc&gclid=123 - Expected: UTM parameters and gclid should be tracked from the URL
- Actual: No attribution tracking happens because referrer matches
excludeReferrers❌
This means any page that's reached via a server-side redirect loses all campaign attribution if you use excludeReferrers, even on the very first page load from an external ad campaign.
Real-world impact: When using Google Tag Manager's Conversion Linker (which preserves gclid in cookies but not UTMs), users see gclid values in their analytics but no UTM parameters, because GTM re-appends gclid but Amplitude's plugin doesn't track the URL parameters when the referrer is excluded.
Environment
- JS SDK Version:
@amplitude/[email protected]@amplitude/[email protected]@amplitude/[email protected](contains the bug)
- Installation Method: NPM
- Browser and Version: All browsers
- Next.js Version: 15.1.6