On 22 October 2026 a Shopify merchant asked r/shopify how other store owners deal with tracking that keeps loading after a visitor clicks Decline. The banner said one thing and the browser did another. This is the most common cookie problem on any platform: the banner records a choice, but nothing on the page is wired to obey it. WooCommerce, Shopify, a headless Next.js or Astro storefront and a plain WordPress site all fail the same way, because the leaks come from embeds, fonts, theme code and tag configuration, not from the banner plugin itself.
This guide shows how to test what your site sends after Decline using only the browser, which requests usually slip through, what Google’s advanced consent mode still transmits by design, and how to gate each one. It cites the EU rules and the vendor documentation behind each point. It is a practical testing guide, not legal advice.
Why tracking still loads after a visitor clicks Decline
The post that started the thread put the split clearly:
App pixels are easy. Shopify handles them. Everything else? YouTube videos, Google Fonts, chat widgets, SEO and analytics scripts: nope. In January 2022, a Munich court awarded a visitor €100 because a website passed the visitor’s IP address to Google through Google Fonts, without consent.
(u/Plus_Cell394, r/shopify, 22 October 2026)
A consent banner only controls what is registered with it. Anything hardcoded in the theme, pasted into a footer field, injected by an embed block or loaded by a plugin that ignores the banner’s API fires on page load regardless of the answer. The banner shows “Declined” and is correct about its own state. The page simply never asked it.
What the EU rule actually covers: not only cookies
Article 5(3) of the ePrivacy Directive covers storing information on, or accessing information from, the visitor’s device. Two primary sources set its reach.
The Court of Justice ruled in Planet49 (C-673/17) that a pre-ticked checkbox is not valid consent, and that the rule applies “whether or not the information stored or accessed” is personal data. The EDPB Guidelines 2/2023 on the technical scope of Article 5(3), version 2.0 adopted on 7 October 2024, go further: JavaScript where the accessing entity “instructs the browser of the user to send asynchronous requests with the targeted information” falls within the scope. The guidelines have separate sections on tracking pixels, local processing and tracking based on IP address only.
So “we set no cookies” does not end the question. A script that reads localStorage or makes the browser ping a third party is in the same territory. The guidelines also note that the rule applying does not automatically mean consent is required, because exemptions exist. Whether one fits your case is a legal question. Whether the request happens at all is a technical one, and that is what you can test.
How to test a cookie banner in browser devtools
Use Chrome, Brave, Firefox or Edge. The steps are the same.
- Open a fresh profile or a private window with extensions off. Ad blockers hide exactly the requests you are looking for.
- Open devtools before loading the page. In the Network tab tick “Preserve log” and “Disable cache”.
- Load the home page and do not touch the banner. Note every third-party domain in the request list. Before any choice, nothing optional should load.
- Click Decline (or Reject all). Then click through a product page, a page with a video, the contact page and the cart. Leaks often sit on templates the home page does not use.
- Filter the request list by domain fragments:
google,gstatic,doubleclick,facebook,tiktok,youtube,hotjar,clarity, the name of your chat vendor. - Open the Application tab (Storage in Firefox) and check Cookies, Local storage and Session storage for each origin. Anything beyond the banner’s own record of the refusal and functional session cookies needs an explanation.
- Repeat with Accept to confirm the tools still work when they are allowed.
Write the results down as a table: domain, page, before choice, after Decline, after Accept. That table is your fix list.
Which requests usually leak after Decline
| Source | How it shows up in Network | Typical cause |
|---|---|---|
| Embedded YouTube or Vimeo | Requests to youtube.com, ytimg.com, googlevideo.com on page load | Plain iframe embed in content or a theme block |
| Google Fonts | fonts.googleapis.com and fonts.gstatic.com | Theme or plugin loads fonts from Google instead of local files |
| Chat widget | Vendor script plus a websocket on every page | Snippet pasted into the footer or theme settings |
| Maps | maps.googleapis.com, map tiles | Store locator or contact page embed |
| Pixels hardcoded in the theme | connect.facebook.net, analytics.tiktok.com, Google Ads tags | Code pasted into header fields, outside the consent system |
| Tag manager tags | Tags fire in GTM preview with consent denied | Tags without consent settings, or triggers on All Pages |
Google’s YouTube help page on embedding describes privacy-enhanced mode (youtube-nocookie.com) as preventing embedded views from influencing the viewer’s YouTube personalization. It does not say the embed sends nothing to Google, so swapping the domain is not a fix by itself.
Fonts are the case with a court ruling. The Munich Regional Court (LG München I, 3 O 17493/20, 20 January 2022) held that passing a visitor’s dynamic IP address to Google through Google Fonts without consent infringed the visitor’s rights, ordered the operator to stop, and awarded 100 euro in damages. The court reasoned that Google Fonts can be used without the browser connecting to a Google server. One commenter in the thread made the same point about scope:
Self-hosting fonts closes that one request.
(u/More_Initiative_9099, r/shopify, 22 October 2026)
Another reply pointed out that the issue is not only European:
This is also a problem in the US. Look up CIPA lawsuits.
(u/hurlbz, r/shopify, 22 October 2026)
Google consent mode v2: what basic and advanced still send
If your Network tab shows requests to Google Analytics after Decline, check which consent mode you run before calling it a leak. Google’s consent mode overview defines two setups:
- Basic: Google tags are blocked until the visitor interacts with the banner. Google states that no data is sent before consent, “not even the default consent status”.
- Advanced: tags load immediately with defaults set to denied. While consent is denied, they send the consent state and “measurements without cookies”. With
analytics_storagedenied, Google Analytics does not read or write its first-party cookies, but measurements are still sent to Google Analytics domains for “basic measurement and modeling purposes”. Withad_storagedenied, requests go through a different domain to avoid previously set ad cookies.
Advanced mode therefore produces Google requests after Decline on purpose. Whether that is acceptable for your site is exactly the Article 5(3) question from the EDPB section above, and it is a decision for you and your adviser, not something the tag can settle. Basic mode is the setup where Decline means no Google request.
Two configuration errors from Google’s implementation guide cause real leaks in either mode. The default consent command must run before any config or event command, otherwise tags fire with no consent state set. And if the banner loads asynchronously, Google says to use wait_for_update so tags wait for the banner’s update instead of firing first. Google also recommends scoping defaults to the regions where you show a banner; a region list that misses a country means visitors there get no denied default at all.
Shopify: Customer Privacy API and app pixels
Shopify’s web pixels documentation says web pixel app extensions honor the Customer Privacy API and, in regions where consent is required, their callbacks run only after consent is given. That is why app pixels behave. Theme code does not get that treatment.
For anything in the theme, use the Customer Privacy API. It exposes analyticsProcessingAllowed(), marketingAllowed() and preferencesProcessingAllowed(), and fires a visitorConsentCollected event when the choice changes. Shopify’s documentation adds that the default depends on the store’s privacy settings: in regions configured to require consent, non-essential purposes are off until consent; elsewhere everything is allowed. Check those settings first, because a region left on the permissive default looks like a broken banner.
The original poster shared a pattern that loads a vendor script only when analyticsProcessingAllowed() returns true, on load and again on visitorConsentCollected. They noted the docs show version 0.2 of the API while their themes had already loaded 0.1 through the banner; that is their observation, and the current documentation shows 0.2.
WooCommerce, WordPress and headless sites
There is no platform-level sandbox here, so the gate is your job. A consent plugin only blocks scripts it knows about. A thread on r/woocommerce in October 2026 about choosing a consent plugin ended up mostly about testing, and one reply named the two gaps that GTM-based setups miss:
Consent Mode only talks to Google tags. Your Meta pixel doesn’t read those signals. […] Not every pixel lives in GTM. WooCommerce plugins (Meta for WooCommerce, Google for WooCommerce and similar) often add their own pixel straight into the page. GTM Preview won’t show those at all.
(u/Bignose_boy, r/woocommerce, 12 October 2026)
The same commenter’s tip: after Accept, two requests to fbevents.js mean the pixel is loaded twice, once by GTM and once by a plugin. Another reply added a case most first-visit tests skip:
I’d also test a returning visitor who withdraws consent without clearing their browser, and someone who accepts analytics but leaves marketing off.
(u/anamap_alex, r/woocommerce, 7 October 2026)
So check three places in the code: header and footer injection fields in the theme or a snippets plugin, plugins that print their own tags (reviews, chat, marketing, the Meta and Google integrations), and embeds stored in post content. Keep cart and session cookies out of the banner’s optional categories: if rejecting empties the cart, a necessary cookie was filed in the wrong group. On a headless frontend the same applies to the root layout and any analytics component. Our GA4 setup guide covers wiring Google tags through consent, and the article on reducing third-party script impact shows how to audit what each script loads.
How to fix each leak
- Embeds (YouTube, Vimeo, maps): replace the iframe with a click-to-load placeholder, a button or thumbnail that creates the iframe only on click or once consent is given. The thumbnail image must be served from your own server, or it is a third-party request too.
- Fonts: download the font files, serve them from your domain with
@font-face, and remove every link to fonts.googleapis.com. - Chat widgets: show a local “Chat with us” button and load the vendor script on click or after consent.
- Hardcoded pixels: move them into the tag manager or the platform’s pixel system, so the consent check applies.
- Tag manager: set consent requirements on every tag, run the default command first, and test in preview with consent denied.
Then rerun the devtools test and fill in the same table. Every row in the “after Decline” column should now show either your own domain or a service you have decided to allow on purpose, with the reason written next to it.
Who enforces this in the UK
The UK rule sits in regulation 6 of PECR. The ICO’s cookies guidance says it applies to “any other type of technology” that stores or accesses information on a device, and notes the page is based on the previous guidance while a revised version on storage and access technologies is under consultation. Check the current page before relying on it.
If you want a second pair of eyes, our WooCommerce EU readiness audit includes the consent test on every template, and the free website check flags third-party requests on a public URL.






