Building a First-Party Analytics Proxy to Bypass Ad Blockers

The problem

Ad blockers don't just block ads — they block analytics too. Most blocklists target known analytics domains (including Application Insights endpoints like js.monitor.azure.com and *.in.applicationinsights.azure.com), which means site owners lose visibility into real traffic patterns. For a personal blog, this can mean 30-40% of visits go untracked.

The first-party proxy pattern

Instead of sending telemetry directly to App Insights endpoints (which get blocked), route it through a first-party path. Since the requests go to your own domain, ad blockers have no reason to block them.

The proxy receives telemetry from the browser, forwards it to App Insights, and returns the response. From the browser's perspective, it's just talking to your own domain.

Two approaches considered

Option A: Azure Container Apps with custom subdomain

Pros: Full control over the runtime, can use C#/.NET, works for any site regardless of hosting platform.

Cons: Extra infrastructure (Container Apps resource, custom domain, TLS cert, container registry, separate deployment pipeline). Overkill when simpler options exist.

Cost: ~$0-2/mo (Container Apps consumption scales to zero, GHCR is free).

Option B: SWA managed function (chosen approach)

Pros: Zero additional infrastructure. Deploys with the site. Already first-party by default. Free on SWA Free tier. Single repo, single pipeline.

Cons: Limited to languages SWA supports for managed functions (Node.js, Python, .NET, Java). Less control over the runtime environment.

Cost: $0 (included in SWA Free tier).

Why Option B wins

For a personal blog already on Azure Static Web Apps, the managed function approach is the obvious choice. There's no reason to stand up a separate Container Apps resource, container registry, and deployment pipeline when SWA gives you a serverless function for free. The proxy endpoint is inherently first-party (same domain), so no custom subdomain or extra DNS setup is needed.

Option A makes more sense if you're hosting on a platform without built-in serverless functions, or if you need C#/.NET specifically, or if you want the proxy to serve multiple sites.

Custom client vs full SDK

A third design decision alongside the proxy approach: do you self-host the full App Insights SDK or write a lightweight custom client?

Full SDK (~36KB gzipped)

Custom client (<1KB inline)

The custom client is the better fit here. Shipping 36KB to call one endpoint goes against the site's minimal-JS philosophy. The browser already exposes everything we need — page load timing, TTFB, DNS lookup, DOM processing — through the Performance API.

Privacy-first design

This isn't about sneaking tracking past ad blockers — it's about getting accurate page view counts while respecting privacy:

The proxy is transparent — it doesn't add any tracking beyond what the original SDK collected. It just ensures the requests actually reach the endpoint, and the custom client ensures the code actually runs.

Open questions

Potential blog post structure

  1. The problem: why your analytics numbers are wrong
  2. The solution: first-party proxy pattern explained
  3. The two infrastructure approaches: standalone container vs built-in platform function
  4. Full SDK vs custom client: why less is more
  5. Building it: SWA managed function + lightweight client walkthrough
  6. Performance metrics for free via the Performance API
  7. Privacy considerations: doing this ethically
  8. Cost: what it actually costs to run (spoiler: $0)