best-practicesUpdated 2025

How to Preserve Original Traffic Sources in GA4

Best practices for maintaining accurate traffic attribution throughout the user journey. Learn when to use UTMs and when to avoid them.

9 min readbest-practices

"Why does GA4 keep changing where my traffic comes from?"

This question comes up constantly in marketing forums. The answer isn't a GA4 bug—it's usually marketers accidentally overwriting their own traffic sources with poorly placed UTM parameters.

Understanding how GA4 tracks traffic sources is the difference between accurate attribution and wasting budget on campaigns that look broken but are actually profitable.

🚨 Not sure what's breaking your tracking?

Run a free 60-second audit to check all 40+ ways UTM tracking can fail.

Scan Your Campaigns Free

✓ No credit card ✓ See results instantly

How GA4 Attribution Actually Works

The Core Rule

GA4 tracks the LAST non-direct traffic source before conversion.

Example user journey:

  1. Monday: User finds you via Google Organic Search

    • GA4 records: Source = google, Medium = organic
  2. Tuesday: User returns by typing your URL directly

    • GA4 keeps: Source = google, Medium = organic (direct traffic doesn't overwrite)
  3. Wednesday: User clicks your email newsletter link

    • GA4 overwrites: Source = newsletter, Medium = email
  4. Thursday: User converts

    • Conversion attributed to: newsletter/email

The email campaign gets credit because it was the last non-direct source.

What Breaks Attribution

Anything that creates a "new" traffic source overwrites the previous one:

  1. UTM parameters on internal links → Creates fake "internal" source
  2. UTM parameters in email signatures (your own domain) → Overwrites real source
  3. Cross-domain tracking not configured → Breaks attribution at domain boundary
  4. Session timeouts → Can reset attribution (rare)

Best Practices for Preserving Attribution

Internal link = Link from your site to another page on your site.

Examples of INTERNAL links (never add UTMs):

Html
<!-- Navigation menu -->
<a href="/products">Products</a>
 
<!-- Footer -->
<a href="/about">About Us</a>
 
<!-- Blog post links -->
<a href="/blog/article">Read more</a>
 
<!-- CTA buttons -->
<a href="/signup">Sign Up</a>
 
<!-- Breadcrumbs -->
<a href="/">Home</a> > <a href="/category">Category</a>

Why: Internal links should be transparent to GA4. Users should browse your site without changing their traffic source.

For internal tracking, use GA4 events instead:

Javascript
// Track internal clicks without destroying attribution
function trackInternalClick(linkText, destination) {
  gtag('event', 'internal_click', {
    'link_text': linkText,
    'destination': destination,
    'page_location': window.location.pathname
  });
}

Rule 2: Only Use UTMs on Traffic Coming TO Your Site

UTM parameters are ONLY for external traffic sources bringing people to your site.

Examples of EXTERNAL sources (use UTMs):

✅ Email campaigns (Mailchimp, HubSpot, etc.)

Code
https://yoursite.com?utm_source=mailchimp&utm_medium=email&utm_campaign=weekly_newsletter

✅ Social media posts

Code
https://yoursite.com?utm_source=linkedin&utm_medium=organic_social&utm_campaign=product_launch

✅ Partner/affiliate links

Code
https://yoursite.com?utm_source=partner_name&utm_medium=referral&utm_campaign=partnership_q1

✅ QR codes

Code
https://yoursite.com?utm_source=qr_code&utm_medium=offline&utm_campaign=conference_2024

✅ Podcast show notes

Code
https://yoursite.com?utm_source=podcast_name&utm_medium=podcast&utm_campaign=episode_42

The rule: If the link exists on a different domain or offline material, use UTMs.

Rule 3: Configure Cross-Domain Tracking

If you have multiple domains (e.g., yoursite.com and shop.yoursite.com), configure GA4 cross-domain measurement.

Without cross-domain tracking:

  • User visits yoursite.com from Google Ads
  • User clicks link to shop.yoursite.com
  • GA4 treats as new session with source = yoursite.com (referral)
  • Original Google Ads attribution lost

With cross-domain tracking:

  • User visits yoursite.com from Google Ads
  • User clicks link to shop.yoursite.com
  • GA4 preserves Google Ads as source
  • Correct attribution maintained

Setup in GA4:

  1. Admin → Data Streams → Web → Configure tag settings
  2. Settings → Configure your domains
  3. Add all your domains:
    • yoursite.com
    • shop.yoursite.com
    • blog.yoursite.com
    • etc.
  4. Save

Update your gtag.js config:

Javascript
gtag('config', 'G-XXXXXXXXXX', {
  'linker': {
    'domains': ['yoursite.com', 'shop.yoursite.com', 'blog.yoursite.com']
  }
});

😰 Is this your only tracking issue?

This is just 1 of 40+ ways UTM tracking breaks. Most marketing teams have 8-12 critical issues they don't know about.

• 94% of sites have UTM errors

• Average: $8,400/month in wasted ad spend

• Fix time: 15 minutes with our report

✓ Connects directly to GA4 (read-only, secure)

✓ Scans 90 days of data in 2 minutes

✓ Prioritizes issues by revenue impact

✓ Shows exact sessions affected

Get Your Free Audit Report

Rule 4: Handle Redirects Properly

UTM parameters must survive redirects.

Problem scenario:

  • User clicks email link: shorturl.com/abc?utm_source=email&utm_medium=newsletter
  • Redirects to: yoursite.com/landing-page
  • UTM parameters lost → Traffic shows as "direct"

Solutions:

Option 1: URL shorteners that preserve parameters

  • Bitly (preserves UTMs automatically)
  • Rebrandly (preserves UTMs)
  • Custom shortener with proper redirect logic

Option 2: Server-side redirect configuration

Javascript
// Node.js example
app.get('/short/:id', (req, res) => {
  const destination = getDestinationURL(req.params.id);
  const queryString = req.url.split('?')[1] || '';
 
  // Preserve query parameters including UTMs
  const redirectURL = queryString
    ? `${"{"}{"{"}destination{"}"}{"}"}}?${"{"}{"{"}queryString{"}"}{"}"}}`
    : destination;
 
  res.redirect(301, redirectURL);
});

Option 3: Add UTMs to final destination

Instead of:

Code
shorturl.com/abc

Use:

Code
shorturl.com/abc (redirects to)
yoursite.com/page?utm_source=email&utm_medium=newsletter&utm_campaign=weekly

Rule 5: Email Signature Best Practices

Your team's email signatures should NOT use UTM parameters when linking to your own website.

Why: When prospects/customers click your email signature, they arrive with UTM parameters that overwrite their original source.

Wrong:

Html
<!-- In email signature -->
<a href="https://yoursite.com?utm_source=email_signature&utm_medium=email">
  Visit Our Website
</a>

What happens:

  1. Customer discovers you via Google Organic Search → browses site
  2. Customer emails your team with a question
  3. You reply with email signature
  4. Customer clicks signature link → GA4 overwrites to "email_signature/email"
  5. Customer converts → Google Organic gets zero credit

Correct:

Html
<!-- In email signature -->
<a href="https://yoursite.com">Visit Our Website</a>

Exception: If signature links to a campaign-specific landing page where you genuinely want to measure email signature performance:

Html
<a href="https://yoursite.com/partners?utm_source=partner_signature&utm_medium=email">
  Partner Program
</a>

Use sparingly and only when measuring specific initiatives.

Rule 6: Session Timeout Considerations

GA4 session timeout: 30 minutes by default

What this means:

  • User visits from Google Ads
  • User browses for 31 minutes (inactive for 31 min)
  • User returns to browsing
  • New session starts with source = direct

Rarely a problem because:

  • Most conversions happen within 30 minutes
  • 30 minutes is industry standard
  • Changing it causes more issues than it solves

When to consider adjusting:

  • Very long-form content (long articles, courses)
  • SaaS apps where users stay logged in but inactive
  • Multi-day research purchases (B2B)

To adjust session timeout (carefully):

Javascript
gtag('config', 'G-XXXXXXXXXX', {
  'session_duration': 60 * 60 * 1000 // 60 minutes in milliseconds
});

Recommendation: Leave at 30 minutes unless you have specific data showing session timeouts are breaking attribution.

Rule 7: SPA (Single Page Application) Considerations

For React, Vue, Angular, etc. sites:

Problem: Page changes don't create new pageviews automatically

Solution: Manually track page changes

Javascript
// React Router example
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
 
function usePageTracking() {
  const location = useLocation();
 
  useEffect(() => {
    // Track page change
    gtag('event', 'page_view', {
      page_path: location.pathname + location.search,
      page_location: window.location.href
    });
  }, [location]);
}

Important: Don't send UTM parameters with every page change:

Javascript
// WRONG - destroys attribution
gtag('event', 'page_view', {
  page_path: '/products?utm_source=internal' // ❌
});
 
// CORRECT - preserve original UTMs
gtag('event', 'page_view', {
  page_path: '/products' // ✓
});

Attribution Preservation Checklist

Use this checklist when implementing any tracking:

  • No UTM parameters on navigation menu
  • No UTM parameters on footer
  • No UTM parameters on internal buttons/CTAs
  • No UTM parameters on breadcrumbs
  • No UTM parameters on related post links
  • Internal behavior tracked via GA4 events (if needed)

For External Campaigns

  • Email campaigns have UTM parameters
  • Social posts have UTM parameters
  • Paid ads use platform auto-tagging (not manual UTMs)
  • Partner/affiliate links have UTM parameters
  • QR codes have UTM parameters

For Cross-Domain

  • All domains listed in GA4 cross-domain settings
  • Linker parameter configured in gtag.js
  • Tested cross-domain attribution

For Team Communication

  • Email signatures use clean URLs (no UTMs)
  • Internal Slack/Teams links use clean URLs
  • Shared documents use clean URLs

✅ Fixed this issue? Great! Now check the other 39...

You just fixed one tracking issue. But are your Google Ads doubling sessions? Is Facebook attribution broken? Are internal links overwriting campaigns?

Connects to GA4 (read-only, OAuth secured)

Scans 90 days of traffic in 2 minutes

Prioritizes by revenue impact

Free forever for monthly audits

Run Complete UTM Audit (Free Forever)

Join 2,847 marketers fixing their tracking daily

Real-World Example: Complete User Journey

Correct attribution preserved throughout:

Day 1: Discovery

User clicks Google Ad

Code
yoursite.com/landing?gclid=ABC123

GA4 records: google/cpc ✓

Day 2: Research

User returns directly (bookmarked page)

Code
yoursite.com/landing

GA4 keeps: google/cpc ✓ (direct doesn't overwrite)

Day 3: Re-engagement

User clicks retargeting email

Code
yoursite.com/offer?utm_source=mailchimp&utm_medium=email&utm_campaign=retarget

GA4 overwrites: mailchimp/email ✓ (legitimate new source)

User browses products (internal navigation, no UTMs)

Code
yoursite.com/products
yoursite.com/products/item-a

GA4 keeps: mailchimp/email ✓

Day 4: Conversion

User converts

GA4 attributes to: mailchimp/email ✓

Result: Accurate attribution shows email retargeting drove the conversion, even though Google Ads started the journey (Google Ads gets "assisted conversion" credit in attribution reports).

FAQ

How do I track which page a user came from without using UTMs?

GA4 automatically tracks this in the page_referrer dimension. You don't need to add anything.

To see internal referral paths:

  1. Reports → Engagement → Pages and screens
  2. Add secondary dimension: Page referrer
  3. See complete internal navigation flow

Remove them immediately. Follow our quick fix guide to restore attribution in 5 minutes.

Can I use UTM parameters for A/B testing different CTAs?

No. Use GA4 events or custom dimensions instead:

Javascript
// Track CTA variant without destroying attribution
gtag('event', 'cta_click', {
  'cta_variant': 'version_a',
  'cta_location': 'header'
});

How long does GA4 preserve the original source?

Until one of these happens:

  1. User clicks link with new UTM parameters
  2. Session expires (30 min inactivity) and user returns directly
  3. User clears cookies/uses new device

For most users: Original source preserved throughout entire journey if you follow best practices.

Should I use UTMs on PDF downloads hosted on my site?

No. PDFs hosted on your domain are internal content.

Track downloads with events:

Javascript
document.querySelectorAll('a[href$=".pdf"]').forEach(link => {
  link.addEventListener('click', function() {
    gtag('event', 'file_download', {
      'file_name': this.pathname,
      'link_text': this.textContent
    });
  });
});

Related: Internal Linking UTM Complete Technical Guide

UTM

Get Your Free Audit in 60 Seconds

Connect GA4, run the scan, and see exactly where tracking is leaking budget. No credit card required.

Trusted by growth teams and agencies to keep attribution clean.