A practice owner asks the web developer to remove the advertising pixel. The developer opens the theme header, finds it, deletes it, confirms the job is done. Three weeks later a scan shows the pixel still firing on every page. Nobody lied, and nobody was careless. The tag was in two places, and tracking tags on WordPress have at least five places to be.
Tracking tags on WordPress do not live in a single location, and there is no admin screen that lists them. They arrive through five distinct mechanisms, controlled by different people at different times, and each behaves differently when you try to gate it. Knowing the five is the difference between an audit that means something and one that produces false confidence.
The five places tracking tags on WordPress actually load
The theme template is the one everybody checks. Code pasted into header.php or a child theme's functions file, usually years ago, usually by someone no longer involved. It is the most durable location, because it survives deactivating every plugin on the site.
Plugin injection is the most numerous. SEO plugins, analytics plugins, chat widgets, booking systems and consent plugins all offer a field for adding code, and practices frequently have the same tag installed twice through two different plugins without realising it. Duplicate installation is not merely untidy; it means removing one leaves the other running and produces exactly the false all-clear described at the top.
The tag manager container is one script that loads an arbitrary number of others. What it loads is decided outside WordPress entirely, in an interface that agencies and contractors are routinely given access to and rarely removed from. A practice can have a clean WordPress installation and an enormous amount of third-party activity through this one line.
Page builder custom code is the one that catches technical people out, and it gets its own section below.
Embedded widgets are the category a gate genuinely cannot reach, which is why they are marked differently above and covered separately in the consent gap in embedded forms.
Worth noting how unevenly these five are distributed across the people who touch a site. The theme is the developer's territory, plugins belong to whoever last logged into the admin, the container is usually the agency's, page-builder code tends to be marketing's, and embeds arrive with whatever vendor the practice signed up for scheduling or reviews. No single person has visibility into all five, and none of them is being negligent. The gaps are organisational before they are technical, which is why asking each party whether the site is clean reliably produces five confident yeses and one dirty page.
Why the plugin list is not the answer
The instinct on being asked what is running is to open the plugins screen and read the list. That list tells you what is installed, not what is loading, and the two diverge in both directions.
Code can persist after the plugin that placed it is gone. A plugin that wrote into theme files, saved a script into a widget area, or stored a snippet in a page-builder global setting leaves that content behind when deactivated, because deactivation removes the plugin's own code and not the content it authored. Meanwhile a single active plugin can be loading a dozen third parties that appear nowhere in its name or description.
This is why an audit should start from the network panel and work backwards to the source, rather than starting from the admin screens and hoping the list is complete. You are looking for the set of domains contacted, and then asking which of the five mechanisms produced each one.
Elementor specifically
Elementor deserves its own treatment because it introduces two locations that do not exist on a plain WordPress site and that experienced developers routinely miss.
The first is Custom Code, a global feature that injects scripts site-wide with a chosen placement of head, body start, or body end. It is functionally a second theme header, it is stored in the database rather than in files, and it is entirely invisible to anyone auditing the theme through a code editor or version control. A tag placed here will survive a theme change, a theme update, and a developer replacing header.php wholesale.
The second is the HTML widget, which allows arbitrary markup inside an individual page's layout. This is where one-off tags accumulate: a campaign pixel added for a promotion in 2023 and never removed, a heat-mapping script added to test one landing page, a third-party review embed. Because it is per-page, a site-wide audit that samples the homepage will not find it, and the pages most likely to carry one are campaign landing pages, which are also the pages most likely to have a form on them.
Why this combination is the worst case
Per-page tags placed by hand tend to live on conversion-focused pages. Conversion-focused pages tend to carry health-intent forms. So the injection point that is hardest to inventory correlates with the page type where disclosure matters most.
Finding tracking tags on WordPress you did not install
A practical sequence that does not require reading anyone's code.
Load the site in a private window with the network panel open and filter to third-party domains, doing nothing with the banner. Record the list. Repeat on a treatment page, a location page and, critically, a page with a form, because these are frequently built differently. Then for each domain, work out which of the five mechanisms produced it: search the theme, search the plugin settings, open the tag manager container, check Elementor Custom Code, and inspect the page for iframes.
Two shortcuts help. Viewing the page source and searching for gtm.js, gtag, fbq and <iframe finds most of it quickly. And a script that appears in the rendered DOM but not in the page source was injected by another script, which almost always means a tag manager.
What to do about each of the five
Four of the five can be held by a gate that operates on the document, because the script is present in your own page and can be withheld until a visitor agrees. That includes the tag manager container, which is worth stressing: gating the loader means nothing inside it runs, so a container full of tags configured by an agency you no longer work with becomes inert without needing access to it. That property is the practical argument in consent mode is not tag blocking, and the mechanism is what consent gating implements.
The fifth is different. A third-party iframe runs in its own context and loads its own resources, and no script on your page can reach inside it. The options there are to gate the embed itself, meaning the frame does not render until consent, or to replace it with a linked destination. Neither is a configuration change, which is why that category needs a decision rather than a setting.
The broader point is that the number of places to look does not shrink over time. Sites accumulate. A practice that resolves all five today and changes agency next year will have a sixth thing to find, which is the argument for a default of nothing rather than a periodic clean-up. Google's own consent implementation guidance is written for the container you control, and the value of a document-level gate is precisely that it does not assume you know what is in the page.
One more failure mode is worth naming because it undoes an otherwise correct job. Caching and optimisation plugins frequently combine and minify scripts, which merges several separate files into one bundle. A gate that identifies scripts by filename or by source domain can be defeated by that merge, because the tag it was told to hold no longer exists as its own request. It is now a few lines inside a combined file the site loads as essential. Practices discover this as a scan that was clean last month and is not clean this month, with nothing having been added.
The fix is ordering rather than argument: the gate has to make its decision before optimisation combines anything, and any caching layer has to be cleared after a consent configuration changes. That is unglamorous and it is where a working setup most often breaks, particularly on sites carrying both a page builder and an aggressive performance plugin, which describes a large share of practice websites.
Whether any of this matters for a given page comes back to what that page collects, which is the analysis in analytics on patient-facing pages. A location page contacting three ad networks is untidy. A consultation form doing the same thing is a different conversation.
Key takeaways
- Five injection points: theme template, plugin injection, tag manager container, page-builder custom code, and embedded third-party widgets.
- The plugin list describes what is installed, not what is loading. Code outlives the plugin that placed it, and one plugin can load many third parties.
- Elementor adds Custom Code, which is a second theme header stored in the database and invisible to file-based audits, and per-page HTML widgets.
- Per-page tags cluster on conversion pages, which are the pages most likely to carry a health-intent form.
- Audit from the rendered page backwards. A script in the DOM but not in the source was injected by another script, usually a tag manager.
- Gating the tag manager loader makes everything inside it inert, including tags configured by an agency you can no longer reach.
Common questions
Where are tracking scripts stored on a WordPress site?
In at least five distinct places: the theme's header or footer template, a plugin that injects code, a tag manager container loaded by any of the above, page-builder custom code settings such as Elementor's, and third-party widgets embedded in page content. They are not listed in any single admin screen, which is why auditing by memory does not work.
Will removing a plugin remove its tracking code?
Usually but not always. A plugin that wrote code into theme files, into the database as a widget, or into a page-builder global setting can leave that code behind after deactivation. The reliable test is to load the page and watch the network requests rather than to reason about what should have been removed.
Can a consent banner block tags it did not install?
It depends on the mechanism. A banner that only sets consent signals reaches tags that support the standard and nothing else. A banner that blocks scripts at the document level can hold anything present in the page source, including scripts placed by other plugins, but generally cannot control what happens inside a third-party iframe.
Sources
- Set up consent mode on websites, Google Tag Platform documentation Reference for how tag manager containers read consent state
- Consent mode overview, Google Tag Platform documentation Documents which tags participate in the standard
Find the tags you did not know were there
The free scan loads your pages the way a visitor does and reports every third-party request, whichever of the five places it came from.