The rule
Google Consent Mode has one strict ordering requirement: the consent default command must execute before the GTM container script loads. The default tells every Google tag what it may do before the visitor has answered the banner. If the container loads first, its tags initialize and can fire in that instant with no consent instruction at all.
The consequences are the worst of both worlds:
- Tags may set cookies and send hits before consent: a compliance problem in the EEA.
- Google receives hits without consent signals, which can disqualify that traffic from conversion modelling in Google Ads and GA4: a data-quality problem.
How the ordering breaks
The default command and the container snippet are usually injected by different pieces of software, and WordPress gives you many ways to get them in the wrong order:
- The consent plugin loads late. The CMP script (which sends the default) is enqueued in the footer or delayed by a performance plugin, while the GTM snippet sits in
<head>. - A cache or optimization plugin reorders scripts. Delayed/deferred JavaScript features move the CMP script behind the container.
- Two plugins each own half the setup. A GTM plugin injects the container early; the consent banner plugin sends the default when it initializes, which happens later.
- The default is bound to banner rendering instead of running inline: no default exists until the banner’s JS executes.
How to verify the order on your site
- Open the page in a private window with DevTools → Console and inspect
window.dataLayerbefore interacting with the banner. - The first consent-related entry must be a
consent defaultcommand, and it must appear before thegtm.jscontainer request in the Network tab’s waterfall. - Tag Assistant shows the same thing in the Consent tab: the default state should be present “on page load”, not appear after container start.
- A Tracking Health Check scan flags this automatically (“consent default fires after the container”).
The fix on WordPress
- Emit the default inline in
<head>, before the container snippet. GTM Kit’s Consent Mode defaults do exactly this: the default command is printed as an inline script guaranteed to run before the container it injects. See Turn on Google Consent Mode v2 defaults. - Exclude both scripts from JS delay/defer. In your optimization plugin, exclude the CMP script and
gtm.jsfrom “delay JavaScript execution”, or the ordering you fixed gets scrambled again at the cache layer. - Let one plugin own the pair. If your CMP integrates with your GTM plugin (or vice versa), use that integration rather than two independent injections racing each other.
- After fixing, re-verify with the steps above, then check that the banner’s accept/decline actually sends a
consent update.