amplitude / amplitude/Amplitude-TypeScript

`excludeReferrers` blocks ALL campaign parameter tracking instead of just referrer attribution

Ouverte
#1,381 3 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
bug
Langage dominant
TypeScript
Étoiles
180
Forks
68
Merge moyen
3 j 1 h
PR mergées (30 j)
29

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 `referrer` and `referring_domain` attribution 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):

```javascript
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:

```javascript
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

1. Configure the Web Attribution Plugin with `excludeReferrers` to exclude your own domain:
```javascript
import { webAttributionPlugin } from '@amplitude/plugin-web-attribution-browser';

const webAttribution = webAttributionPlugin({
excludeReferrers: [/yourdomain\.com$/]
});

amplitude.add(webAttribution);
await amplitude.init('YOUR_API_KEY');
```

2. 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 ✅

3. 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 ❌

4. 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`):

1. User clicks Google Ad landing on: `https://yourdomain.com/pricing?utm_source=google&utm_medium=cpc&gclid=123`
2. Server performs redirect (with query parameters preserved): `https://yourdomain.com/product/pricing?utm_source=google&utm_medium=cpc&gclid=123`
3. 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/analytics-browser@2.29.0`
- `@amplitude/plugin-web-attribution-browser@2.1.92`
- `@amplitude/analytics-client-common@2.4.11` (contains the bug)
- Installation Method: NPM
- Browser and Version: All browsers
- Next.js Version: 15.1.6

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.