ConsentStackDocs

Script Blocking

ConsentStack automatically detects and blocks third-party scripts until your visitors give consent.

ConsentStack finds the third-party scripts running on your site and blocks them until your visitors consent to the relevant category. No manual tagging required for known scripts. It just works.

How scripts are detected and categorized

When a visitor loads your page, ConsentStack scans for third-party scripts and checks each one against a built-in database of 900+ known tracker patterns from 900+ vendors. If a script belongs to a recognized vendor (Google Analytics, Meta Pixel, HubSpot, and hundreds more) it is automatically assigned to the right consent category.

Scripts from domains that are not in the database are flagged as unassigned in your dashboard so you can review and categorize them yourself.

Two ways to categorize scripts

MethodHow it worksWhen to use it
AutomaticConsentStack recognizes the script's domain and assigns a category based on its known vendor database.Works out of the box for the vast majority of third-party scripts. No action needed.
Manual rulesYou create a custom rule in the dashboard for a specific domain, assigning it to any category you choose.For proprietary or niche scripts that the vendor database does not cover.

Manual rules always take priority. If you create a custom rule for a domain that is already auto-categorized, your rule wins.

What blocking looks like in practice

Scripts are stopped before they execute, not cleaned up after the fact. This is an important distinction: no tracking code runs until your visitor has actively given consent for that category.

When a visitor gives consent:

  • Blocked scripts activate immediately. There is no page reload required. Scripts in the consented category start running right away, in their original page order. If a tracker has multiple scripts (for example, a config script and a pageview script), they execute in the correct sequence: the config script loads and finishes before the pageview script starts.

When a visitor revokes consent:

  • Already-executed scripts cannot be un-run. A script that has already loaded and sent data cannot be retroactively stopped. ConsentStack shows the visitor a gentle reminder to refresh the page, which clears the scripts from memory and re-applies blocking.

The key trust signal: scripts are blocked before execution, not cleaned up afterward. Your visitors' data is never sent to a third party without their consent.

For developers

If you need more control, you can manually tag any script with a data-cs-category attribute to assign it to a specific consent category. This is useful for inline scripts or cases where you want to override automatic detection.

For implementation details, see SDK installation.

The preload-scanner caveat

ConsentStack intercepts third-party scripts at the moment their src is set in JavaScript. This catches every standard tracker bootstrap pattern (Google Tag Manager, HubSpot, Microsoft Clarity, Meta Pixel, and so on) when they are injected via JS. It does not catch tags written directly into the initial HTML such as <script async src="..."> or <link rel="preload" as="script">. The browser's preload scanner walks the markup ahead of the parser and dispatches fetches for those URLs before any JavaScript runs. The third party receives the request and may set cookies on its own domain even though the script's execution is later blocked.

Two situations make this matter:

  1. Plain HTML / Webflow / WordPress where you paste a vendor's <script async src="..."> snippet straight into the head.
  2. SSR'd Next.js layouts where <Script> and @next/third-parties (<GoogleTagManager>, <GoogleAnalytics>) emit <link rel="preload" as="script"> into the rendered HTML.

Solution: opt-in markup with application/cs-resolve

For tags written directly in HTML, mark them with a non-executable type so the preload scanner ignores them. ConsentStack walks these tags after consent is determined and rewrites them to the executable form for any category the visitor has granted.

<!-- External script: parser will not fetch -->
<script type="application/cs-resolve" async
        src="https://www.googletagmanager.com/gtag/js?id=AW-XXXXX"></script>

<!-- Inline script: requires data-cs-category since there is no src to look up -->
<script type="application/cs-resolve" data-cs-category="analytics">
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date()); gtag('config', 'AW-XXXXX');
</script>

<!-- Stylesheet: parser will not fetch until rel is rewritten -->
<link rel="cs-stylesheet" href="https://example.com/widget.css">

How classification works:

  1. If data-cs-category is set, that category is used (always wins).
  2. Otherwise, the tag's src (or href) domain is matched against the catalog. Hundreds of common vendors are auto-classified.
  3. If neither resolves a category, the tag stays dormant.

Inline scripts have no src to classify, so they require an explicit data-cs-category. External scripts and stylesheets from known vendors do not.

Many widget libraries (Calendly, Intercom, HubSpot, Drift) inject their own styles when their script initializes, so a separate <link> for the stylesheet is often redundant. Try removing the <link> first; only mark it with rel="cs-stylesheet" if the widget visibly breaks without it.

Solution: SSR-emitted preloads in Next.js

For frameworks that auto-emit preloads, two patterns avoid the leak:

  • Inline the bootstrap snippet with dangerouslySetInnerHTML. The inline <script> has no src, so no preload is emitted, and the runtime injection it performs is intercepted normally. This is the simplest pattern for layout-level trackers. See Framework Guides for the full pattern.
  • Gate <Script> on a consent hook. Wrap it in a client component that returns null until useConsentValue reports the relevant category as granted. The SSR pass renders null, so no preload appears in the initial HTML.

What's next

  • Learn about consent models and how ConsentStack decides what your visitors see
  • See how to review and manage detected scripts in the dashboard