All Articles
Feature image for server-side-tagging-on-a-gatsby-or-nextjs-site-why-and-how

Server-Side Tagging on a Gatsby or Next.js Site: Why and How


What server-side tagging actually is

Traditional Google Tag Manager runs in the user's browser. Every pixel (GA4, Meta, TikTok, LinkedIn) loads a script, fires from the client, and sends data directly to the vendor. Server-side tagging (SST) moves that work off the browser and onto a server you control. The browser sends one request to your own endpoint, and that endpoint fans out to the vendors on your behalf.

It sounds like a small architectural shift. The consequences are large.

Why it now matters

Four things have quietly made client-side tagging unreliable over the last few years.

Cookie lifetimes

Apple Safari's ITP caps third-party cookies at 7 days, and any first-party cookie set via client-side JavaScript (which is how the _ga cookie works) is capped at 7 days too. On iOS, returning visitors look like new users after a week. Server-set first-party cookies via Set-Cookie headers are not capped the same way. SST lets you set those.

Ad blockers

uBlock Origin and friends block google-analytics.com, googletagmanager.com, and facebook.net by default. Between 20 and 40 percent of technical audiences run an ad blocker. SST serves tags from your own domain (for example metrics.yourbrand.com), which blockers leave alone.

Consent and compliance

Client-side tags fire before consent is granted, then get "suppressed" by Consent Mode. Server-side tagging lets you enforce consent at the server boundary. Nothing leaves the server until signals are explicitly permitted. Cleaner for audits, cleaner for DPOs.

Data ownership

With SST you see the raw payloads before they go to any vendor. You can redact PII, enrich with CRM data, or route the same event to three destinations without loading three scripts in the browser.

Core Web Vitals wins

This is the surprise benefit for most clients. A marketing site loads 6 to 12 third-party tags client-side: GA4, GTM, Meta Pixel, LinkedIn Insight, Hotjar, HubSpot, Intercom chat. Each one costs JavaScript parse time, network round trips, and a layout shift or two.

Moving these behind SST reduces total blocking time by 200 to 600 milliseconds and can shave 0.5 to 1.0 second off Largest Contentful Paint on mobile. That matters because Core Web Vitals are a ranking signal and directly affect conversion.

Architecture options

There are three realistic paths.

Google Tag Manager Server container on Google Cloud Run

Google's official path. You deploy a Docker image to Cloud Run, point a subdomain (via CNAME) at it, and configure tags in the GTM Server UI. Cost is usage-based, roughly AUD $40 to $120 per month for a site doing 100k to 500k pageviews. You manage the infrastructure.

Stape.io (or similar managed hosts)

Stape is the most popular managed SST host. They run the GTM Server container for you, handle autoscaling and SSL, and offer power-ups like Meta CAPI gateways and GA4 cookie extensions. Plans start around USD $20 per month. For most Aussie SMBs, this is the right choice. You get SST without running Docker.

Custom Node or edge function

For teams with engineering capacity, a bespoke endpoint on Vercel, Cloudflare Workers, or Fastly Compute is cheaper, faster, and fully under your control. You build your own event schema, forward to GA4 Measurement Protocol and Meta CAPI yourself. More flexible, more maintenance.

Implementation on Next.js

On a Next.js site, the cleanest pattern is:

  • Install @next/third-parties for the client GTM snippet, pointed at your SST endpoint rather than googletagmanager.com.
  • Proxy the GTM container JS through a Next.js rewrite (next.config.js rewrites) from /metrics/gtm.js to your SST host. This keeps the request on your own origin.
  • For server-sent events (backend-triggered conversions, webhooks), POST directly from a Route Handler to the SST endpoint using a shared secret header. This lets Stripe or HubSpot webhooks feed the same analytics pipeline as the browser.
  • Use the X-Gtm-Server-Preview header in dev mode to hit GTM Server's preview environment without polluting production.

Implementation on Gatsby

Gatsby sites are mostly static, which simplifies the picture.

  • Use gatsby-plugin-google-tagmanager with the includeInDevelopment: false flag and point the dataLayerName at the SST loader.
  • Configure a custom subdomain (for example metrics.yourbrand.com) via your CDN. On Netlify this is a rewrite in _redirects; on Cloudflare Pages it is a Worker route.
  • Set selfHostedOrigin in the plugin config to load the GTM JS from your SST host instead of googletagmanager.com.
  • Fire events via window.dataLayer.push() as usual. The client code does not change, only where it loads from.

First-party cookies done right

The biggest single win from SST is setting the GA4 _ga and _ga_XXXX cookies server-side via Set-Cookie headers with HttpOnly omitted (GA4 needs to read them in JS) and a two-year Max-Age. On Safari, this can lift the reported returning-user count by 30 to 50 percent over a few months. It is not magic. Those users were always there. They were just invisible to your old setup.

When it is overkill

SST is not free. It adds a deployment, a monthly cost, and a failure domain. For a small business site doing under 10,000 monthly visitors, running basic GA4 with no ad spend and no compliance pressure, client-side tagging is fine. Revisit the decision once you have real money riding on attribution, or once you are running paid social at scale and need reliable Meta CAPI delivery.

What to test before going live

A broken SST setup is worse than no SST. Your analytics goes silent and nobody notices until the end-of-month report. Before swapping production traffic over, we run through a short checklist.

  • Load the site in Chrome with the Network tab filtered to your SST domain. Confirm the GTM library loads from metrics.yourbrand.com and not googletagmanager.com.
  • Fire a test conversion and check that GA4 DebugView picks it up, then confirm it appears in the GA4 real-time report within a minute.
  • Check that the Meta Events Manager shows the matching server event with a strong event match quality score (above 7.0 is healthy).
  • Clear cookies, reload, and verify first-party cookies are set by the server with Set-Cookie and a two-year Max-Age, not by client-side JavaScript.
  • Run the site through PageSpeed Insights before and after. Total blocking time should drop noticeably on mobile.

Only once all five pass do we switch DNS or feature-flag the new loader on for the full audience. Done properly, this takes a day of careful QA and saves weeks of chasing phantom data issues later.

Getting started

At CodeDrips, we build Gatsby and Next.js sites with SST as a standard option for clients doing serious marketing. If your analytics data feels flaky or your pixels keep breaking, let's talk about moving your tagging server-side.

Related articles

Feature image for ga4-for-business-owners-the-only-7-reports-that-matter

GA4 for Business Owners: The Only 7 Reports That Matter

GA4 overwhelms most business owners with hundreds of reports. Here are the seven that actually drive decisions — and how to read each one without a degree in analytics.

Read Article
Feature image for building-for-the-au-market-gst-abn-validation-and-auspost-integration

Building for the AU Market: GST, ABN Validation and Auspost Integration

Global SaaS rarely handles the Australian basics well. Here is the practical plumbing for ABN validation, GST edge cases, and Australia Post integration on an AU-first website.

Read Article
Feature image for google-business-profile-and-website-the-au-local-discovery-stack-in-2026

Google Business Profile and Website: The AU Local Discovery Stack in 2026

Local discovery in Australia changed meaningfully in 2025 and 2026. Here is how your Google Business Profile, website, and directories need to work together now.

Read Article

Web Development services we offer

More ArticlesGet In TouchEmail Us