Keep Dev Traffic Out of Analytics in Astro
The Problem with Running Everything in Development
You’re working on your blog locally, testing changes, clicking through your own site, and having a great time building. Meanwhile, your Google Analytics dashboard is filling up with dev traffic that skews your real visitor metrics. Or worse—you accidentally click your own AdSense ads a few times, and Google’s fraud detection flags your account.
Sound familiar? This is a surprisingly common oversight, but it’s easily preventable.
Why This Matters
Analytics Pollution
Every time you refresh the page during development, you’re adding noise to your analytics data. Real visitors’ behavior becomes harder to track when mixed with your own testing sessions.
Ad Fraud Detection
Google takes ad clicks seriously. Clicking your own ads—whether intentional or accidental during testing—can trigger fraud detection algorithms and put your AdSense account at risk.
Unnecessary Network Requests
Third-party scripts add latency and bandwidth. In development, there’s no reason to load these dependencies when you’re focused on building features.
The Solution: Environment-Based Conditionals
If you’re using Astro, you have a built-in way to detect your build environment using import.meta.env.PROD. This flag is true during production builds and false during development.
Before: Always Loaded
---
// BaseHead.astro
---
<!-- Google Analytics - Always loads, even in dev! -->
<script is:inline src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script is:inline>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "G-XXXXXXXXXX");
</script>
<!-- Google AdSense - Always loads, even in dev! -->
<script
is:inline
async
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-XXXXXXXXXX"
crossorigin="anonymous"></script>
After: Production Only
---
// BaseHead.astro
---
<!-- Google Analytics - Only in production -->
{import.meta.env.PROD && (
<>
<script is:inline src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script is:inline>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "G-XXXXXXXXXX");
</script>
</>
)}
<!-- Google AdSense - Only in production -->
{import.meta.env.PROD && (
<script
is:inline
async
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-XXXXXXXXXX"
crossorigin="anonymous"></script>
)}
How It Works
When you run astro dev, the development server builds with import.meta.env.PROD = false. The conditional expressions {import.meta.env.PROD && (...)} evaluate to false, and the scripts don’t render at all.
When you run astro build, the production build uses import.meta.env.PROD = true. The conditionals evaluate to true, and the scripts are included in your final HTML.
Key Benefits
✅ Clean Analytics — Only real visitor data in your dashboards
✅ Fraud Protection — Zero risk of accidental ad clicks triggering detection
✅ Faster Dev — Fewer network requests means snappier local development
✅ Build-Time Detection — Zero runtime overhead; this is all compiled away
✅ No Extra Config — Uses Astro’s native environment detection
Beyond Google: Apply This Pattern Everywhere
This approach works for any third-party script you want to gate behind a production build:
{import.meta.env.PROD && (
<>
<!-- Sentry error tracking -->
<script src="https://browser.sentry-cdn.com/..."></script>
<!-- Custom analytics service -->
<script src="https://analytics.example.com/track.js"></script>
<!-- Heatmap/session replay tools -->
<script src="https://sessionreplay.example.com/record.js"></script>
</>
)}
Any performance monitoring, user tracking, or promotional script can be safely gated this way.
Verification
After making these changes, you can verify they’re working:
Check your dev build:
npm run dev
# Open DevTools → Network tab
# Look for googletagmanager.com requests
# ✓ They shouldn't appear
Check your production build:
npm run build
# Open dist/index.html in a text editor
# Search for "googletagmanager"
# ✓ It should be there
Conclusion
Conditionally loading external scripts is a small change with big benefits. It keeps your analytics clean, protects your ad accounts from fraud detection, and speeds up your development workflow. Best of all, Astro makes it trivial to implement with built-in environment detection.
If you’re not already doing this, add it to your next deployment. Your analytics dashboard will thank you. 📊