# UTM Cleanup Best Practices

**Last Updated:** 2026-01-29

## Overview

This document outlines best practices for UTM parameter cleaning based on industry research and implementation analysis.

## Core Principles

### 1. Timing is Critical

**Rule:** UTMs must ONLY be removed AFTER analytics tools have captured the data.

**Implementation:**
- Wait for analytics scripts to load
- Use analytics callbacks when possible
- Minimum delay: 1.5 seconds
- Maximum delay: 3 seconds (prevent infinite wait)

**Current Implementation:**
- Waits for GTM dataLayer
- Waits for HubSpot script
- Waits for page load
- Proceeds when ready OR after 1.5s minimum

### 2. Preserve Critical Parameters

**Rule:** Some parameters must be preserved for conversion tracking.

**Preserve:**
- `hsa_*` parameters (Google Ads conversion tracking)
- `gad_source`, `gbraid` (Google Ads tracking)

**Remove:**
- `utm_*` parameters (prevent misattribution)
- `gclid` (session-specific, captured in cookies)
- `leadSource`, `partner`, `signuptype` (internal tracking)

### 3. Multiple Fallback Mechanisms

**Rule:** Ensure tracking works even if cleanup fails.

**Fallbacks:**
1. Instance variables (persist after cleanup)
2. Cookies (90-day expiration)
3. localStorage (cross-domain fallback)
4. URL parameters (last resort)

**Current Implementation:**
- Forms read from instance variables first
- Fall back to cookies
- Fall back to localStorage
- Backend reads from form fields, then page_url, then cookies

### 4. Monitor and Alert

**Rule:** Track cleanup success/failure for early detection.

**Metrics:**
- Cleanup success rate (target: >95%)
- Cleanup duration
- Analytics capture timing
- Error rate

**Alerts:**
- Success rate < 90%
- Error rate > 10%
- Duration > 100ms
- Analytics capture delay > 2s

### 5. Feature Flag for Testing

**Rule:** Allow quick enable/disable for A/B testing.

**Implementation:**
- Feature flag in localStorage
- Quick rollback capability
- A/B testing support

**Usage:**
```javascript
// Disable
localStorage.setItem('utmCleanupEnabled', 'false');

// Enable
localStorage.setItem('utmCleanupEnabled', 'true');
```

## Implementation Guidelines

### When to Clean

**Clean UTMs:**
- After analytics capture
- Before user shares link
- On page load (after delay)

**Don't Clean:**
- Before analytics capture
- On internal navigation (use `preventInternalUTMCarryover()`)
- If analytics scripts fail to load (fallback to keeping UTMs)

### Error Handling

**Best Practices:**
- Graceful failure (don't break page)
- Log errors for monitoring
- Fallback to keeping UTMs if cleanup fails
- Track errors in analytics

**Current Implementation:**
- Try-catch around cleanup
- Error events dispatched
- Errors sent to dataLayer
- Graceful degradation

### Performance Considerations

**Best Practices:**
- Minimal performance impact (< 50ms)
- Non-blocking execution
- Efficient URL manipulation
- Cache-friendly

**Current Implementation:**
- ~7ms overhead (negligible)
- Non-blocking (async)
- Efficient URLSearchParams API
- No performance impact

## Testing Guidelines

### Test Scenarios

1. **Analytics Capture:**
   - Verify GTM/GA4 capture before cleanup
   - Verify HubSpot capture (may be async)
   - Test with slow networks

2. **Form Tracking:**
   - Test form submission after cleanup
   - Verify UTM data in form fields
   - Test with cookies disabled

3. **Link Sharing:**
   - Test copy/paste scenarios
   - Test share via email
   - Test share via social media

4. **Edge Cases:**
   - Browser compatibility
   - Private/Incognito mode
   - Cookies disabled
   - JavaScript disabled

### Test Scripts

- `test-analytics-timing.php` - Analytics capture timing
- `test-link-sharing-scenarios.php` - Misattribution scenarios
- `test-cleanup-performance.php` - Performance impact
- `test-cleanup-monitoring.php` - Monitoring/alerting

## Monitoring Guidelines

### Key Metrics

1. **Cleanup Success Rate**
   - Target: >95%
   - Alert if < 90%

2. **Analytics Capture Timing**
   - Target: < 2s
   - Alert if > 3s

3. **Form Attribution Accuracy**
   - Target: 100%
   - Alert if < 95%

4. **Performance Impact**
   - Target: < 50ms
   - Alert if > 100ms

### Monitoring Setup

1. **GTM Events:**
   - `utm_cleanup_complete` - Success
   - `utm_cleanup_error` - Failure

2. **GA4 Custom Events:**
   - Track cleanup events
   - Monitor success rates
   - Alert on errors

3. **Dashboards:**
   - Cleanup status dashboard
   - Analytics timing dashboard
   - Form tracking dashboard

## Troubleshooting

### Cleanup Not Working

**Check:**
1. Feature flag enabled? `localStorage.getItem('utmCleanupEnabled')`
2. UTMs in URL? Check `window.location.search`
3. Analytics scripts loaded? Check `window.dataLayer`, `window.hubspotScriptLoaded`
4. Errors in console? Check for `utmCleanupError` events

**Solution:**
- Enable debug mode: `?utm_debug=true`
- Check console logs
- Verify feature flag
- Check analytics script loading

### Analytics Not Capturing

**Check:**
1. Analytics scripts loaded?
2. UTMs removed too early?
3. Network issues?
4. Consent mode blocking?

**Solution:**
- Increase cleanup delay
- Check analytics script loading
- Verify consent mode
- Test with debug mode

### Forms Missing UTMs

**Check:**
1. Cookies set? `document.cookie`
2. Instance variables set? `window.utmTracker.utm_source`
3. Form fields populated? Check form HTML
4. Backend reading correctly? Check form-hs.php logs

**Solution:**
- Check cookies/localStorage
- Verify form field population
- Check backend logs
- Test with debug mode

## Related Documentation

- `docs/development/UTM_TRACKING_DEBUGGING.md` - Debugging guide
- `docs/development/UTM_CLEANUP_IMPROVEMENTS.md` - Improvements
- [`UTM_CLEANUP_FINAL_RECOMMENDATION.md`](../archive/2026-04-01-docs-cleanup/utm-cleanup-analysis/UTM_CLEANUP_FINAL_RECOMMENDATION.md) — Recommendation (archived analysis)
