What is Tag Gateway?

Tag Gateway is a first-party tracking solution that routes your Google tracking requests through your own domain instead of directly to Google's servers. This makes tracking requests appear as first-party traffic, helping them bypass ad blockers and browser privacy restrictions.

In Simple Terms

Instead of your website sending data directly to googletagmanager.com (which ad blockers recognise), Tag Gateway sends it through yourdomain.com/gtag/ first. Your server then forwards it to Google. The result? More conversions tracked, better data accuracy.

Key Benefits

  • Bypass ad blockers — Requests from your own domain aren't blocked
  • Recover lost conversions — Capture 15-30% more conversion data
  • First-party cookies — Longer cookie lifespans (90 days vs 7 days)
  • Better attribution — More accurate ROAS and campaign data
  • ITP compliance — Works with Safari's Intelligent Tracking Prevention

Why Tag Gateway Matters for E-Commerce

For Google Shopping advertisers, conversion tracking accuracy directly impacts campaign performance. When Google can't see your conversions, Smart Bidding can't optimise effectively.

42% of users have ad blockers installed (2025)
15-30% Conversions typically lost to blocking
7 days Third-party cookie lifespan in Safari
90 days First-party cookie lifespan

The Impact on Google Ads

  • Smart Bidding signals — Google needs conversion data to optimise bids. Missing conversions = suboptimal bidding.
  • ROAS calculation — Understated conversions mean your reported ROAS is lower than reality, leading to conservative budget decisions.
  • Audience building — Remarketing lists miss users who weren't tracked, reducing audience size and quality.
  • Attribution accuracy — Cross-device and multi-touch attribution suffers without complete conversion data.

The Impact on Profit Optimisation

Accurate tracking isn't just about reporting — it directly affects profit-based bidding. When you use MarginStack to manage per-SKU costs and ProfitClarity to calculate profit-driven ROAS targets, the accuracy of those targets depends entirely on how many conversions you can see. If 30% of conversions are invisible, your ROAS calculations are 30% off.

GROW Platform Integration

The GROW Platform includes a Tracking Accuracy setting in ProfitClarity™ that compensates for tracking loss in bid calculations. Even with Tag Gateway, we recommend setting this to 85-95% to account for users who block all tracking.

How Tag Gateway Works

Tag Gateway acts as a reverse proxy between your website and Google's tracking servers. Here's the technical flow:

Standard Tracking (Blocked)

Browsergoogletagmanager.com Blocked by ad blocker

Tag Gateway Tracking (Works)

Browseryourdomain.com/gtag/Your ServerGoogle Conversion recorded

Technical Requirements

  • Proxy endpoint — A server or edge function that forwards requests to Google
  • HTTPS — Your proxy must use SSL (standard for all modern sites)
  • Same domain — The proxy must be on your main domain or a subdomain
  • Header forwarding — Client IP and user-agent must be passed to Google

Implementation Options

Method Difficulty Cost Best For
Cloudflare Workers Easy Free (100k req/day) Most e-commerce sites
Cloudflare Pages Functions Easy Free tier available Static sites on Cloudflare
Google Cloud Run Medium Pay-per-use (~$5-20/mo) Google-native stacks
Nginx/Apache Proxy Advanced Server costs Self-hosted platforms
Platform Apps Easy Varies ($10-50/mo) Shopify, BigCommerce

Implementation Guide

Choose your implementation method below. We recommend Cloudflare Workers for most e-commerce sites due to its simplicity and generous free tier.

Cloudflare Workers Setup

Cloudflare Workers run at the edge, close to your users. This is the easiest and most performant option for most sites.

Step 1: Create the Worker

  1. Log in to your Cloudflare Dashboard
  2. Go to Workers & PagesCreate Worker
  3. Name your worker (e.g., gtag-proxy)
  4. Replace the default code with the following:
// Cloudflare Worker - Tag Gateway Proxy
export default {
  async fetch(request) {
    const url = new URL(request.url);

    // Only handle /gtag/* paths
    if (!url.pathname.startsWith('/gtag/')) {
      return new Response('Not found', { status: 404 });
    }

    // Rewrite to Google's servers
    const googlePath = url.pathname.replace('/gtag/', '/');
    const googleUrl = 'https://www.googletagmanager.com' + googlePath + url.search;

    // Forward the request
    const response = await fetch(googleUrl, {
      method: request.method,
      headers: request.headers,
      body: request.method !== 'GET' ? request.body : undefined
    });

    // Return with CORS headers
    const newHeaders = new Headers(response.headers);
    newHeaders.set('Access-Control-Allow-Origin', '*');

    return new Response(response.body, {
      status: response.status,
      headers: newHeaders
    });
  }
};

Step 2: Configure the Route

  1. Go to Workers → Your Worker → Triggers
  2. Click Add Route
  3. Enter: yourdomain.com/gtag/*
  4. Select your zone and save

Step 3: Update Your Tracking Code

Change your gtag.js script from:

<!-- Old: Direct to Google (gets blocked) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=GT-XXXXX"></script>

To:

<!-- New: Through your domain (not blocked) -->
<script async src="https://yourdomain.com/gtag/gtag/js?id=GT-XXXXX"></script>

Cloudflare Pages Functions

If your site is hosted on Cloudflare Pages, you can use Functions to proxy without a separate Worker.

Step 1: Create the Function

Create the file functions/gtag/[[path]].js in your project:

// functions/gtag/[[path]].js
export async function onRequest(context) {
  const url = new URL(context.request.url);

  // Rewrite to Google's servers
  const targetUrl = new URL(
    url.pathname + url.search,
    'https://www.googletagmanager.com'
  );

  // Forward the request
  const proxyRequest = new Request(targetUrl.toString(), {
    method: context.request.method,
    headers: context.request.headers,
    body: context.request.method !== 'GET'
      ? context.request.body : undefined,
    redirect: 'follow'
  });

  const response = await fetch(proxyRequest);

  // Add CORS headers
  const newHeaders = new Headers(response.headers);
  newHeaders.set('Access-Control-Allow-Origin', '*');
  newHeaders.set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');

  return new Response(response.body, {
    status: response.status,
    headers: newHeaders
  });
}

Step 2: Deploy

Deploy your site as normal. The function will automatically handle /gtag/* requests.

Nginx Configuration

For self-hosted sites, add this to your Nginx configuration:

# Nginx Tag Gateway Proxy
location /gtag/ {
    proxy_pass https://www.googletagmanager.com/;
    proxy_set_header Host www.googletagmanager.com;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_ssl_server_name on;

    # CORS headers
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
}

Apache Configuration

Enable mod_proxy and mod_proxy_http, then add:

# Apache Tag Gateway Proxy
<Location /gtag/>
    ProxyPass https://www.googletagmanager.com/
    ProxyPassReverse https://www.googletagmanager.com/

    Header set Access-Control-Allow-Origin "*"
    Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
</Location>

Google Cloud Run Setup

Deploy a containerised proxy service on Google Cloud Run.

Step 1: Create the Service

Create a simple Node.js proxy:

// server.js
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');

const app = express();

app.use('/gtag', createProxyMiddleware({
  target: 'https://www.googletagmanager.com',
  changeOrigin: true,
  pathRewrite: { '^/gtag': '' },
  onProxyRes: (proxyRes) => {
    proxyRes.headers['access-control-allow-origin'] = '*';
  }
}));

app.listen(process.env.PORT || 8080);

Step 2: Deploy to Cloud Run

gcloud run deploy gtag-proxy \
  --source . \
  --region europe-west1 \
  --allow-unauthenticated

Step 3: Configure Custom Domain

Map your Cloud Run service to tracking.yourdomain.com or use a load balancer to route /gtag/* to the service.

E-Commerce Platform Setup

Once your Tag Gateway proxy is running, update your tracking code on your e-commerce platform.

Shopify Setup

Option 1: Theme Code (Recommended)

  1. Go to Online StoreThemesEdit code
  2. Open theme.liquid
  3. Find and replace the Google tag script URL:
<!-- Replace this: -->
<script async src="https://www.googletagmanager.com/gtag/js?id=GT-XXXXX"></script>

<!-- With this: -->
<script async src="https://yourdomain.com/gtag/gtag/js?id=GT-XXXXX"></script>

Option 2: Checkout Scripts

For conversion tracking on checkout (Shopify Plus required):

  1. Go to SettingsCheckoutAdditional scripts
  2. Update the gtag.js URL to your Tag Gateway endpoint
Shopify Apps

Several Shopify apps offer Tag Gateway functionality. Search the App Store for "server-side tracking" or "first-party tracking". These typically cost $10-50/month but require no technical setup.

WooCommerce Setup

Using a Plugin

If you use a Google Analytics plugin (e.g., MonsterInsights, GA4 for WooCommerce), check if it supports custom tracking endpoints. Otherwise, use the manual method.

Manual Setup

Add this to your theme's functions.php or a custom plugin:

// Add Tag Gateway tracking to WooCommerce
add_action('wp_head', function() {
    ?>
    <!-- Google tag via Tag Gateway -->
    <script async src="https:///gtag/gtag/js?id=GT-XXXXX"></script>
    <script>
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', 'GT-XXXXX');
    </script>
    <?php
}, 1);

For Thank You Page Conversions

Ensure your conversion tracking on woocommerce_thankyou uses the same Tag Gateway URL.

Magento / Adobe Commerce Setup

Option 1: Module Configuration

If using Magento's built-in Google Analytics module or a third-party extension, look for a "custom endpoint" or "tracking URL" setting.

Option 2: Layout XML

Create a custom module or override the default head block:

<!-- app/design/frontend/[Theme]/[Theme]/Magento_Theme/layout/default_head_blocks.xml -->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <head>
        <script src="https://yourdomain.com/gtag/gtag/js?id=GT-XXXXX"
                src_type="url" async="true"/>
    </head>
</page>

Option 3: RequireJS Configuration

For complex setups, you may need to modify RequireJS configuration to route Google Analytics requests through your proxy.

Custom / Other Platforms

The principle is the same for any platform:

  1. Find where the Google tag script is loaded
  2. Change the src URL from googletagmanager.com to your proxy endpoint
  3. Ensure any fetch() or sendBeacon() calls also use your proxy
<!-- Standard implementation -->
<script async src="https://yourdomain.com/gtag/gtag/js?id=GT-XXXXX"></script>
<script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());
    gtag('config', 'GT-XXXXX');
</script>
GTM Users

If using Google Tag Manager, you need to proxy googletagmanager.com rather than google-analytics.com. The GTM container will then load Analytics through your proxy automatically.

GCLID Tracking for Google Ads

For Google Shopping campaigns, capturing the GCLID (Google Click ID) is essential. This unique identifier links ad clicks to conversions and powers offline conversion tracking.

What is GCLID?

When someone clicks a Google Ad, a gclid parameter is added to the URL:

https://yourdomain.com/product?gclid=EAIaIQobChMI...

Why Capture It?

  • Offline conversion tracking — Match sales data back to the original ad click
  • Cross-domain tracking — Pass GCLID from marketing site to checkout
  • CAPI integration — Required for server-side conversion uploads
  • Extended attribution — 90-day attribution window with stored GCLIDs

Implementation

Add a GCLID tracker script that captures and stores the click ID:

// GCLID Tracker - add to your site's <head>
(function() {
    const GCLID_KEY = 'grow_gclid';
    const EXPIRY_DAYS = 90;

    // Extract GCLID from URL
    function getGclidFromUrl() {
        const params = new URLSearchParams(window.location.search);
        return params.get('gclid');
    }

    // Store in localStorage + cookie
    function storeGclid(gclid) {
        if (!gclid) return;

        // localStorage (primary)
        localStorage.setItem(GCLID_KEY, gclid);
        localStorage.setItem(GCLID_KEY + '_ts', Date.now());

        // Cookie (backup, cross-subdomain)
        const expires = new Date(Date.now() + EXPIRY_DAYS * 86400000);
        document.cookie = GCLID_KEY + '=' + gclid +
            ';expires=' + expires.toUTCString() +
            ';path=/;SameSite=Lax;Secure';
    }

    // Initialize
    const gclid = getGclidFromUrl();
    if (gclid) storeGclid(gclid);
})();
Next: CAPI Tracking

GCLID capture is step one. To upload conversions server-side, you need CAPI (Conversion API) tracking. This sends conversion data directly to Google from your server, bypassing all browser-based blocking. Read the CAPI Tracking guide →

Testing & Validation

After implementing Tag Gateway, verify it's working correctly.

Quick Tests

  • Browser Network Tab — Open DevTools, check that gtag requests go to your domain, not googletagmanager.com
  • Ad Blocker Test — Enable an ad blocker, verify your site still sends tracking requests
  • Real-Time Reports — Check GA4 Real-Time to confirm hits are arriving
  • Google Ads — In Tag Assistant or Diagnostics, verify conversions are recording

Checklist

Test Expected Result If Failing
Load /gtag/gtag/js?id=GT-XXX Returns JavaScript, 200 status Check proxy route configuration
Network tab shows your domain Requests go to yourdomain.com/gtag/ Script URL not updated
Works with ad blocker on Requests still sent Confirm first-party domain
GA4 Real-Time shows visits Active users appear Check proxy forwarding
Conversions track in Google Ads Test conversion appears Check GCLID + conversion tag

Best Practices

Do
  • Use your main domain (not a subdomain like tracking.site.com)
  • Set up monitoring/alerting for your proxy
  • Test with multiple browsers and devices
  • Combine with CAPI for maximum coverage
  • Keep proxy code simple and fast
Don't
  • Don't assume 100% tracking — some users block everything
  • Don't forget to update checkout/thankyou pages
  • Don't use obvious paths like /google-analytics/
  • Don't skip GDPR consent — Tag Gateway doesn't exempt you
  • Don't cache proxy responses (data must be live)
Privacy Compliance

Tag Gateway improves tracking reliability but doesn't change your privacy obligations. You still need GDPR consent before tracking EU users. The GROW Platform integrates with Google Consent Mode v2 to handle this correctly.

Next Steps

Tag Gateway is the first layer of a robust conversion tracking stack. For maximum data accuracy, combine it with server-side conversion tracking.

Complete Tracking Strategy

Tag Gateway is layer one (recovering client-side tracking). CAPI tracking is layer two (server-side conversion uploads). Together, they maximise tracking accuracy — which directly improves the performance of profit-based bidding in ProfitClarity. The more conversions you capture, the more accurate your per-SKU ROAS targets become.

Layer What It Does Coverage
Tag Gateway (this guide) First-party tracking, bypasses ad blockers ~85-95% of users
CAPI Tracking Server-side conversion uploads, offline sales 100% of completed sales
Enhanced Conversions First-party customer data matching Improves attribution accuracy

GROW Your |

Deliver on your commitment to cut costs, improve profit margins & grow sales, with smart automation tools.

GROW is a profit-first automation layer for global e-commerce brands — turning real-time COGS and CAC data into fully automated, SKU-level advertising that can launch, rebuild, and update millions of products in minutes.