A Site's Entire Ad Mess Traced Back to One Unmodified Script Tag

Ad placements on this site had started looking wrong — not broken, just not deliberate: spots that clearly weren't ones I remembered choosing. My first assumption was that some old ad unit had been dropped into a template years ago and half-forgotten, so I went looking for it in the theme. There's exactly one ad-related line in the entire theme, and it isn't a placement at all:

<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5072092791126294" crossorigin="anonymous"></script>

Sitting in html.html.twig, loaded on every page. No <ins class="adsbygoogle"> anywhere — no manual ad unit, no slot ID, no size, no placement markup at all, in this file or anywhere else in the theme. That absence is the actual answer: this is Google's Auto ads loader, not a hand-placed ad. With Auto ads, the site owner doesn't choose where ads go in code at all — enabling the feature in the AdSense dashboard is the entire integration, and Google's own algorithm decides format, position, and density on the page by scanning the rendered content client-side. The commit that eventually cleaned up an unrelated script in this same file names the placement problem directly and correctly routes around it: fixing where an ad appears here isn't a code change, because the code was never what decided that in the first place. It's a dashboard setting, not a template bug.

I checked the obvious alternative before settling on that answer: nothing in this site's version-controlled Drupal configuration mentions AdSense or ads at all, and no ads-related contrib module appears in core.extension.yml. If there were a config-managed ad module involved, at least the mechanism would show up in a config diff somewhere in sync/, even if the actual placement logic lived in the module's own code rather than this site's. There's nothing — the entire footprint of this site's advertising is that one script tag, and everything downstream of it happens outside anything this repository can see or control.

A second, unrelated finding in the same file

While tracing through html.html.twig looking for that answer, there was a second script tag sitting a few lines below it, loaded unconditionally on every single page for over two years past being useful:

<script src="https://www.googleoptimize.com/optimize.js?id=OPT-KKXWD8M"></script>

Google shut Google Optimize down in September 2023. This tag had been requesting a script from a product that no longer exists since then — not erroring loudly, just a silent failed request against a domain nobody at Google was serving traffic for anymore, on every page load, for roughly two years, without doing anything at all. Removing it was a one-line diff and had zero relationship to the ad-placement question that sent me into the file in the first place; it was purely a byproduct of reading a template top to bottom while looking for something else.

Two different kinds of dead weight, back to back

What's worth pulling apart here is that these are two structurally different problems that happened to sit in the same nine lines of markup. The Optimize script was inert — it referenced a service that had stopped existing, so removing it changed nothing observable about the page except one less failed request. The AdSense script is the opposite: very much alive, doing exactly what it was told to do, and the surprising part isn't that it's broken but that "what it was told to do" isn't specified anywhere I could grep for. A hand-placed ad unit is a decision you can find, read, and change in the codebase. An Auto ads loader is a decision you made once, in a web dashboard, that keeps re-deciding on Google's terms every time the page renders — the code doesn't encode the decision, it just grants permission for one to keep being made elsewhere.

That distinction is the actual lesson, more than either individual finding. When something on a page looks wrong and the instinct is to go read the template, it's worth checking first whether the thing controlling that behavior is even in the template at all. A single unconditional script tag with no configuration next to it is often not an incomplete implementation waiting to be found — it's the entire implementation, deliberately, with everything else about it living in an admin panel that a code search will never surface. Two completely different debugging strategies apply depending on which situation you're actually in, and reading the surrounding eight lines of markup was enough to tell them apart here — but only because I stopped assuming "the ad code" meant something I could find and edit before I'd actually confirmed it.

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
Please share this article on your favorite website or platform.