# UTM Cleanup Page Exclusions

**Last Updated:** 2026-03-11

## Overview

UTM cleanup is disabled on specific pages where it's not desired. This is configured in the feature flag system.

## Excluded Pages

The following pages have UTM cleanup disabled:

1. **`/v3`** (and all `/v3/*` paths)
   - Routes to: `v2/pages/landingpage_v3.php`
   - Reason: Page-specific requirement

2. **`/gastro`**
   - Routes to: `v2/pages/paid_nonbrand.php`
   - Reason: Page-specific requirement

3. **`/schichtbetriebe`**
   - Routes to: `v2/pages/paid_schichtbetriebe.php`
   - Reason: Page-specific requirement

4. **`/paid`**
   - Routes to: `v2/pages/paid_paid.php`
   - Reason: Page-specific requirement

5. **`/kostenlos-testen`**
   - Routes to: `v2/pages/kostenlos-testen.php`
   - Reason: Page-specific requirement

## Implementation

The exclusion logic is implemented in multiple places to ensure comprehensive protection:

### 1. Feature Flag (`v2/js/utm-cleanup-feature-flag.js`)

```javascript
const PAGES_WITHOUT_CLEANUP = ["/v3", "/gastro", "/schichtbetriebe", "/paid", "/kostenlos-testen"];
```

The feature flag checks the current page pathname and disables cleanup if it matches any excluded path (exact match or starts with excluded path + '/').

### 2. UTM Tracker (`v2/js/utm-tracking.js`)

The UTM tracker has exclusion checks in three places:
- At the start of `setupUTMCleanup()` method
- Inside the `waitForAnalyticsReady()` callback
- At the start of `cleanUTMParametersFromURL()` method

### 3. Pricing Page Script (`v2/js/pricing-page.js`) ⚠️ CRITICAL

**IMPORTANT:** The `pricing-page.js` script contains URL cleaning logic that runs immediately on page load (via IIFE) and removes ALL URL parameters, including UTMs, BEFORE the UTM tracker can initialize. This affects `/gastro` and `/schichtbetriebe` pages which include `pricing-page.min.js`.

The pricing-page.js script has been modified to check for excluded pages before cleaning URLs:

```javascript
// Clean URL on page load if it has parameters (but NOT on excluded pages)
(function() {
  // Check if page is excluded from URL cleaning
  const excludedPages = ['/v3', '/gastro', '/schichtbetriebe'];
  const currentPath = window.location.pathname;
  const isPageExcluded = excludedPages.some(path => 
    currentPath === path || currentPath.startsWith(path + '/')
  );
  
  // Skip URL cleaning on excluded pages
  if (isPageExcluded) {
    console.log('[Pricing Page] URL cleaning skipped - Excluded page:', currentPath);
    return;
  }
  
  // Only clean URL if it has parameters AND page is not excluded
  if (window.location.search) {
    const cleanUrl = new URL(window.location.origin + window.location.pathname);
    window.history.replaceState({}, '', cleanUrl.toString());
  }
})();
```

**Note:** `/v3` page does NOT include pricing-page.js, so it doesn't have this interference issue.

## Behavior

On excluded pages:

- ✅ UTM parameters remain in URL
- ✅ Analytics still capture UTMs (normal behavior)
- ✅ Form tracking still works (uses cookies/instance variables)
- ✅ Internal link carryover prevention still works (separate feature)

## Testing

To verify cleanup is disabled on excluded pages:

1. **Visit excluded page with UTMs:**

   ```
   http://localhost:8003/v3?utm_source=test&utm_campaign=test&utm_debug=true
   http://localhost:8003/gastro?utm_source=test&utm_campaign=test&utm_debug=true
   http://localhost:8003/schichtbetriebe?utm_source=test&utm_campaign=test&utm_debug=true
   http://localhost:8003/paid?utm_source=test&utm_campaign=test&utm_debug=true
   http://localhost:8003/kostenlos-testen?utm_source=test&utm_campaign=test&utm_debug=true
   ```

2. **Check browser console:**
   - Should see: `[UTM Cleanup] Cleanup disabled for excluded page: /v3`
   - UTMs should remain in URL after page load

3. **Verify on non-excluded page:**
   ```
   http://localhost:8003/schichtplan?utm_source=test&utm_campaign=test&utm_debug=true
   ```

   - UTMs should be removed from URL after cleanup

## Adding/Removing Exclusions

To add a new exclusion:

1. Edit `v2/js/utm-cleanup-feature-flag.js`
2. Add path to `PAGES_WITHOUT_CLEANUP` array:
   ```javascript
   const PAGES_WITHOUT_CLEANUP = [
     "/v3",
     "/gastro",
     "/schichtbetriebe",
     "/paid",
     "/kostenlos-testen",
     "/new-excluded-page", // Add here
   ];
   ```
3. No minification needed (file is small)
4. Test the exclusion works

To remove an exclusion:

1. Remove path from `PAGES_WITHOUT_CLEANUP` array
2. Test cleanup works on that page

## Troubleshooting

### Issue: Cleanup Still Happening Despite Exclusion

If cleanup is still executing on excluded pages:

1. **Check Browser Console:**
   - Look for exclusion messages: `[UTM Cleanup] Cleanup DISABLED via excluded page`
   - Look for pricing-page messages: `[Pricing Page] URL cleaning skipped - Excluded page`
   - Check for JavaScript errors
   - Verify feature flag loaded

2. **Check Pathname:**
   ```javascript
   window.location.pathname; // Should match excluded path
   ```

3. **Check Feature Flag:**
   ```javascript
   window.utmCleanupFeatureFlag.getStatus();
   ```

4. **Verify Scripts Loaded:**
   - Check Network tab for `utm-cleanup-feature-flag.js`
   - Check Network tab for `utm-tracking.min.js`
   - Check Network tab for `pricing-page.min.js` (on /gastro and /schichtbetriebe)
   - Verify scripts load in correct order

5. **Check Pricing Page Script (for /gastro and /schichtbetriebe):**
   - Verify pricing-page.js has exclusion logic (lines 386-406)
   - Verify pricing-page.min.js was regenerated after changes
   - Check console for `[Pricing Page] URL cleaning skipped` message
   - Run `npm run minify` to regenerate pricing-page.min.js if needed

## Related Documentation

- `docs/development/UTM_CLEANUP_IMPROVEMENTS.md` - Feature flag system
- `docs/development/UTM_CLEANUP_BEST_PRACTICES.md` - Best practices
- `docs/development/UTM_CLEANUP_SCRIPT_INTERFERENCE.md` - Script interference documentation
- `v2/js/utm-cleanup-feature-flag.js` - Feature flag implementation
- `v2/js/pricing-page.js` - Pricing page script with exclusion check
