Back to the blog

Blog

Google Ads with server-side tagging: how each conversion finds its ad click

Published · 6 min read

Setting up conversion tracking in Google Ads ends with two requests: link your existing Google tag, and paste an event snippet on your purchase page. With server-side tagging the first is fine and the second is a mistake. This article follows one ad click from the landing page to a conversion in Google Ads — what passes through your tagging server, what goes straight to Google, and what SignalHost takes care of on the way. We run Google Ads for signalhost.io ourselves, so everything here was measured on our own site.

What changes when you link your Google tag

When you create a conversion action, Google Ads looks for a Google tag on your site and offers to use it. Accept, and your Google tag — the one with your G- measurement ID — gets your Ads account (AW-…) as a second destination. Google warns that this updates the tag's settings. The change is made in Google's tag settings, not in your Tag Manager container, but from then on every page that loads the tag also talks to Google Ads.

Each page view now sends a few requests from the visitor's browser straight to Google, to googleads.g.doubleclick.net and www.google.com, for your remarketing lists and Google's own measurement. They do not pass through your tagging server, and that is deliberate: relayed through a server, every one of them would arrive from the server's address instead of the visitor's, which is not what you want an ad platform to see. Your GA4 data keeps flowing through your own domain as before.

New to server-side tagging? How server-side Google Tag Manager is set up, step by step.

Keep Google's conversion snippet off your page

Next, Google Ads offers an event snippet for your purchase page. It sends the conversion from the browser straight to Google Ads, past your tagging server — with a value of 1.0 and an empty transaction ID unless someone fills them in.

// Google's event snippet: not for your page.
// Paste it into the Conversion ID box in SignalHost instead.
gtag('event', 'conversion', {
  'send_to': 'AW-123456789/AbC-D_efGh12_34',
  'value': 1.0,
  'currency': 'EUR',
  'transaction_id': ''
});

With SignalHost your server container sends the conversion instead. Open your container, fold out Conversion destinations and enter the conversion ID and label under Google Ads. From then on every purchase your site already reports, the GA4 purchase event, goes to Google Ads from the server, with its value, currency and transaction ID. Nothing in your Tag Manager has to change.

Do not add the snippet as well. With both, each purchase is recorded twice: Google merges two conversions only when they carry the same transaction ID, and the snippet's is usually empty.

You do not have to pick the ID and label out of the snippet yourself. Paste the whole snippet, or just its send_to value, into the Conversion ID box and both fields fill in. The ID works either way, AW-123456789 or 123456789.

How the ad click survives until the purchase

A conversion is only useful to Google Ads if it can be tied to the click that led to it. The tie is the click ID: Google adds it to your landing page's address as gclid=…, and it is gone from the address with the visitor's next click.

Every SignalHost container has a server-side Conversion Linker for this. It reads the click ID from the landing page's hit and stores it in a first-party cookie called FPGCLAW, on your domain. When the purchase arrives — three pages or three days later — the Google Ads tag in your server container reads that cookie and sends the conversion together with the click.

Two things have to hold. The visitor must allow advertising in your cookie banner: without that consent the linker stores nothing and the Ads tag sends nothing. And the browser must accept the cookie, which depends on the address your tagging server runs on.

Why Google Ads needs your own domain

The click cookie is set by your tagging server, and browsers only accept it when that server belongs to your own website — a subdomain such as metrics.yoursite.com. The address every container starts with is a subdomain of signalhost.io, which to the browser is someone else's website, so there the cookie is refused.

Nothing reports the difference. Conversions still reach Google Ads, but without their click, so Google Ads cannot credit them to a campaign — which looks exactly like ads that do not work. Link your own domain before you judge a campaign by its numbers: it takes one CNAME record, and the certificate is issued automatically. Until a domain is active, the Google Ads settings of your container say so. How to point your own domain at your tagging server.

When the purchase happens days later

Trials and subscriptions break the usual path: the money moves days after the visit, when nobody is on your site, so the purchase has to be sent from your server — usually from your payment provider's webhook, as our guide to custom checkouts describes.

For Google Ads, that purchase needs two more things from the checkout, while the visitor is still there. Store the advertising cookies the checkout request carries — FPGCLAW, FPAU and Google's _gcl_ cookies, which only exist once the visitor allowed advertising — and send them back as cookies with the purchase, with advertising consent marked as granted. Without them Google Ads can neither accept the conversion nor credit it.

// At checkout: keep the advertising cookies with the order.
// They only exist once the visitor allowed advertising.
const AD_COOKIES = ['FPGCLAW', 'FPAU', '_gcl_aw', '_gcl_au'];
order.adCookies = pick(req.cookies, AD_COOKIES);

// In the payment webhook: send them back with the purchase.
// gcs=G111 in the params: advertising and analytics consent granted.
await fetch(`https://metrics.yoursite.com/g/collect?${params}`, {
  method: 'POST',
  headers: { cookie: serialize(order.adCookies) },
});

This is how signalhost.io reports its own subscriptions: the Stripe webhook sends the purchase when the first invoice is paid, and it carries the ad click from the checkout.

What SignalHost takes care of

You enter two values. Everything else is part of every container:

  • The Conversion Linker and the Google Ads conversion tag. Entering an ID and a label switches them on with the next request.
  • The Ads tag fires on purchases and on nothing else. A tag that heard every event would record each page view as a sale.
  • Advertising consent is enforced on the server: a visitor who declined advertising produces no conversion in Google Ads.
  • Every cookie your tagging server sets reaches the browser — the click ID, the first-party visitor ID and the ad user ID.
  • The conversion ID is sent in the form the tag expects, however you typed it.
  • Your container page tells you when Google Ads is missing your own domain.

signalhost.io runs on exactly this setup with our own Google Ads account. The check we rely on is a test visit with a click ID: it has to end with the click cookie in the browser.

Checking your own setup

  • Open your site with ?gclid=test at the end of the address and allow advertising in your cookie banner. Among your browser's cookies for your domain you should now find FPGCLAW.
  • Start a preview session under Developer tools on your container, press Preview on your server container in Tag Manager and make a test purchase. The Google Ads conversion tag should fire on it, with value, currency and transaction ID filled in.
  • Make sure Google's event snippet is not on your purchase page, and that no Google Ads conversion tag in your web container fires on the same purchase.
  • Give Google Ads a day: a new conversion action can take that long to show as active.

If conversions arrive but are never credited to a campaign, the click is being lost on the way: check the consent choice and your own domain first.

Stop losing data to ad blockers

Ten thousand requests a month, free, for as long as you like. Four minutes to find out whether it helps.