A 200 Is Not Proof (The Redirect That Eats Your gclid)
A redirect can return a 301 to the right page and still strip the gclid from every ad click. The conversion comes back attached to nothing. The check.
47.66° N 117.43° W Summit · Profitable Growth
In early August 2026 a landing page went live on a client’s ad destination with one meta tag set to preview instead of production. The page loaded. It looked finished. The form accepted a submission and returned a success panel. Underneath, the form never called the API, the analytics tags never loaded, and every lead would have died with the browser tab. The campaign was enabled against that URL. I caught it before a single click was paid for.
Landing pages built for paid traffic usually carry a switch that separates a preview build from a live one. When that switch is wrong, the page still works in every way a person can see. It renders, it takes a form, it says thank you. What it stops doing is recording. So I verify the destination before the campaign spends rather than after the first report comes back empty. Five of the six checks run from a terminal in under two minutes. The sixth needs a person.
The page carries a single line in its head:
<meta name="deployment-mode" content="production">
The page reads that value at runtime and gates everything measurable on it. Set to production, the form posts to the lead API and the GA4 and Google Ads tags load and fire. Set to anything else, the form short-circuits to a “Preview complete” panel and never reaches the network call. The tags load nothing at all.
The gate is one line of JavaScript, and its bluntness is the point:
if (mode !== 'production') { show(LAST + 1); return; } // never reaches fetch()
That design is correct. A preview build should be incapable of writing a real lead into a client’s CRM, and it should be incapable of polluting a conversion action with test submissions. The flag exists so a staging copy can be circulated for review without any of it counting.
The failure mode is that the same property which makes preview safe makes it silent. There’s no error state. Nothing turns red. A page in preview mode and a page in production mode are visually identical right through the thank-you screen. The only way to tell them apart is to read the tag or watch the network.
The build was a paid-only page for a custom furniture maker taking commission work. Static assets on Cloudflare Pages, two Pages Functions behind them, leads flowing to WhatConverts.
I was doing a pre-launch pass on the live URL, not the preview URL, and I pulled the raw HTML rather than looking at the rendered page. That’s the only reason I saw it. deployment-mode read preview. The Search campaign pointed at that exact URL and was already enabled.
Two other things surfaced in the same pass, both from the same deploy. The first: the repo root had been deployed instead of the public/ directory, so README.md and .gitignore were being served at the site origin and both returned HTTP 200 on a live client site. The second: wrangler resolves the functions/ directory relative to the working directory rather than the asset directory you hand it, so a deploy run from the wrong folder ships the static assets without the Functions. The tell is that /api/lead starts answering 404 where it should answer 405.
Then a fourth problem, which is the one worth remembering. The apex domain runs on Google Cloud DNS, so it’s not a Cloudflare zone. No caching panel, no zone id, no purge_cache call. Deleting the stray README.md didn’t evict it. The edge kept serving the deleted file with CF-Cache-Status: HIT under a seven-day TTL. The fix was to overwrite the path with new content so the ETag changed, which replaced the cached response immediately.
This is now a script rather than a memory. It runs against the live URL, never the preview URL, and it fails loudly:
deployment-mode from the served HTML. Not the local file, not the preview origin. Fetch the URL the ad points at.GET /api/lead should answer 405. A 404 means the Functions didn’t deploy and the form has nowhere to post.invalid_json means the secrets are wired. lead_system_not_configured means they’re missing and the handler is failing closed.Steps one through five are automated and take seconds. Step six is the only one that proves anything, and it’s the one most launches skip.
The cost isn’t a bad campaign. It’s an invisible one.
Traffic arrives. Clicks bill. People fill out the form and see a confirmation, so nobody complains. The leads never reach the CRM and the conversions never reach the ad platform, which means Smart Bidding is optimizing against an empty signal and steering budget by nothing at all. Every day it runs, the bidding model learns from noise.
The report at the end of the month shows spend and clicks and zero conversions, and the conversation that follows is about whether the offer is wrong or the keywords are wrong. That’s a hard hole to climb out of, because the account now has a stretch of history that says the traffic doesn’t convert, and none of it is true. I wrote about that exact symptom in clicks with no conversions. A misconfigured destination produces the same chart as a genuinely bad campaign.
The flag was found on 2026-08-05 on a live Cloudflare Pages deployment with the Search campaign already enabled. The stray README.md at the origin returned HTTP 200 and kept serving from cache under s-maxage=604800 after deletion, which is what forced the overwrite-instead-of-delete fix. /api/lead returned 404 until the second deploy shipped the Functions bundle, then 405 as expected. The verification script now checks the deployment flag, both tag IDs, the conversion label, the bot-protection key, all seven sitelink and price anchors, and the endpoint status on every relaunch. Conversions on that page fire only after the API returns a lead id, so the conversion count can never exceed the leads delivered. The measurement architecture underneath is the same one in the Tracking Stack.
The deploy-pipeline version of this problem, where the build itself is what drops the flag, is in Four Ways a Site Launch Lies to You.
Pull the HTML of the page your ads point at right now and read it. Not the rendered page. The source. If you want the longer version of that pass, the Google Ads Setup Checklist is the twenty-five page checklist I run on accounts before I touch anything, and it’s free with no email required.
If you’re about to launch a site or a campaign and want a second read before it spends, send me read-only access for the free ads audit. It comes back in writing within 24 hours. No call.
From the answer library
More reading
A redirect can return a 301 to the right page and still strip the gclid from every ad click. The conversion comes back attached to nothing. The check.
Four page paths in my analytics project have never existed on my site. A pitch mockup carried the same public key. The provenance check that finds it.
Free ads audit, written by me
Add me as a read-only user and I'll write the audit myself: 5 to 7 pages, back within 24 hours of access. A home or furniture store can send the store link instead. Rather talk first? A call is open too.