Cookie banner says Declined but tracking still loads: how to test and fix it

Cookie banner says Declined but tracking still loads: how to test and fix it

Last verified: October 23, 2026
11 min read
Guide
Security auditor
Marketing strategist

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.

Use Chrome, Brave, Firefox or Edge. The steps are the same.

  1. Open a fresh profile or a private window with extensions off. Ad blockers hide exactly the requests you are looking for.
  2. Open devtools before loading the page. In the Network tab tick “Preserve log” and “Disable cache”.
  3. 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.
  4. 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.
  5. Filter the request list by domain fragments: google, gstatic, doubleclick, facebook, tiktok, youtube, hotjar, clarity, the name of your chat vendor.
  6. 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.
  7. 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

SourceHow it shows up in NetworkTypical cause
Embedded YouTube or VimeoRequests to youtube.com, ytimg.com, googlevideo.com on page loadPlain iframe embed in content or a theme block
Google Fontsfonts.googleapis.com and fonts.gstatic.comTheme or plugin loads fonts from Google instead of local files
Chat widgetVendor script plus a websocket on every pageSnippet pasted into the footer or theme settings
Mapsmaps.googleapis.com, map tilesStore locator or contact page embed
Pixels hardcoded in the themeconnect.facebook.net, analytics.tiktok.com, Google Ads tagsCode pasted into header fields, outside the consent system
Tag manager tagsTags fire in GTM preview with consent deniedTags 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)

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_storage denied, 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”. With ad_storage denied, 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.

Next step

Turn the article into an actual implementation

This block strengthens internal linking and gives readers the most relevant next move instead of leaving them at a dead end.

Related cluster

Explore other WordPress services and knowledge base

Strengthen your business with professional technical support in key areas of the WordPress ecosystem.

Frequently asked questions

Practical answers to apply the topic in real execution.

Does a cookieless request still need consent#
Possibly. The EDPB guidelines treat JavaScript that makes the browser send information as gaining access to the device, and Planet49 says the rule applies whether or not the data is personal. Whether an exemption fits is a legal assessment for your case, but no cookie does not mean out of scope.
Is youtube-nocookie.com enough to stop YouTube tracking#
No. Google describes privacy-enhanced mode as stopping embedded views from personalizing the viewer's YouTube experience. It does not say the embed makes no requests to Google. A click-to-load placeholder that creates the iframe only after a click or consent is what keeps the request from happening.
Why do Shopify app pixels behave but my theme scripts do not#
Web pixel app extensions run in Shopify's sandbox and honor the Customer Privacy API automatically. A script pasted into theme.liquid or a section runs outside that sandbox, so it loads on every page view until you wrap it in a check such as analyticsProcessingAllowed() or marketingAllowed().
Is self-hosting Google Fonts enough to fix the Munich problem#
For fonts, yes: the Munich court's reasoning was that Google Fonts can be used without the browser connecting to a Google server. Check that no plugin, theme or embed still loads fonts.googleapis.com or fonts.gstatic.com after the change.

Need an FAQ tailored to your industry and market? We can build one aligned with your business goals.

Let’s discuss

Related Articles

PHP2Shell: is my WordPress site at risk and what to do

PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, released on 21 October 2026, fix two critical vulnerabilities in PHP itself (CVE-2026-109618, CVE-2026-109619). How to check the PHP version in WordPress, what to do when your host has not updated the server yet, and which passwords to change after the update.