Blog
Google Ads with server-side tagging: how each conversion finds its ad click
Published · Updated · 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 Google Ads card 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 pick Google Ads. Choose the event that records the conversion — a purchase, a lead, a sign-up, a booking, any event your site sends — and the card shows which category to create the conversion action in, in Google Ads. Then enter the conversion ID and label. From then on, every time your site sends that event it goes to Google Ads from the server, with its value, currency and transaction ID. Add up to four more conversion actions, each with its own event and label. 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 paste box on the Google Ads card — or straight 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 conversion reaches Google Ads only as the cookieless signal Consent Mode sends for modelling, never tied to a click. 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.
Record consent separately at checkout and check the currently applicable permissions again before sending the later payment event. Cookies alone do not prove consent. The code below is only a transport excerpt: checkoutConsent and currentConsent must come from your consent system, and buildPurchaseParamsForConsent must preserve all four actual Consent Mode states. Never change denied or unknown purposes to granted.
// Transport excerpt only. Implement these integration helpers in your app.
// Consent records come from your consent system, never from cookie presence.
const mayUseAdCookies = (consent) =>
consent?.appliesToPurchase === true &&
consent?.withdrawn === false &&
consent?.analytics_storage === 'granted' &&
consent?.ad_storage === 'granted';
// At checkout: retain cookies only with separately recorded permission.
const AD_COOKIES = ['FPGCLAW', 'FPAU', '_gcl_aw', '_gcl_au'];
order.adConsentAtCheckout = checkoutConsent;
order.adCookies = mayUseAdCookies(checkoutConsent)
? pick(req.cookies, AD_COOKIES)
: null;
// In the payment webhook: re-read current applicable consent from your system.
// The required builder must encode all four ACTUAL Consent Mode states.
// It must preserve denied purposes; this excerpt does not implement that builder.
if (!mayUseAdCookies(currentConsent)) {
order.adCookies = null;
} else if (mayUseAdCookies(order.adConsentAtCheckout) && order.adCookies) {
const params = buildPurchaseParamsForConsent(invoice, currentConsent);
await fetch(`https://metrics.yoursite.com/g/collect?${params}`, {
method: 'POST',
headers: { cookie: serialize(order.adCookies) },
});
}Use this pattern as a starting point for your own payment-webhook integration. Implement consent recording, applicability and withdrawal checks, and consent-aware event parameters in your application. Transmission does not guarantee acceptance by Google or attribution to an ad.
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.
- Each conversion action fires on its own event — purchase unless you choose another — and on nothing else. A tag that heard every event would record each page view as a sale.
- Consent Mode is respected on the server: a visitor who declined advertising is never tied to an ad click or added to your remarketing lists, and reaches Google Ads only as the cookieless signal its conversion modelling uses.
- 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.
- Press Send test conversion on the Google Ads card. It records one conversion for each conversion action, carrying no ad click, so it is never credited to a campaign — and a new action stops reading as incomplete in Google Ads.
- Start a preview session under Developer tools on your container, press Preview on your server container in Tag Manager and trigger your conversion — a test purchase, or whichever event you chose. The Google Ads conversion tag should fire on it, with the value, currency and transaction ID the event carries.
- 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.

