Skip to content
  • There are no suggestions because the search field is empty.

Controlling When Halda Fires Based on Visitor Consent

How Halda is installed

Halda is added to a site as a single <script> tag. Once loaded, that script does three things:

  1. Tracks metadata events (page views, widget views, form submits, search submits, etc.).
  2. Optionally forwards those metadata events to third-party analytics you have configured (Google Analytics / GTM).
  3. Injects Halda widgets (search, hub, AHA, slide-out, embedded and click-to-pop forms).

Because it is a normal script tag, you have two independent levers to make it respect consent. You can use either or both.


Option A — Suppression on Denial

Halda ships with a consent listener that suppresses Halda's tracking the moment it detects that a visitor has denied analytics/marketing consent. You do not have to wire anything up for this to work.

Recognized consent platforms: OneTrust, Cookiebot, CookieYes, Osano, any CMP implementing the IAB TCF v2 API (__tcfapi), and the browser-level Global Privacy Control signal.

What happens on a denial: On a live denial, Halda stops event tracking and stops forwarding anything to third-party analytics, and it injects no further widgets. Any widgets already on the page are left in place but go inert (their tracking stops). If a denial is already known at page load (a remembered denial, a GPC signal, or a deny cookie), Halda does not boot at all, so no widgets are injected in the first place. The choice is remembered for future page views (stored in the browser) and mirrored across open tabs. If the visitor later allows consent, Halda comes back on.

Important — this is "fail-open": Halda runs by default and only switches off on an affirmatively detected denial. An un-answered banner, an unrecognized CMP, or an unparseable consent cookie all leave Halda running. This matches a US opt-out model. If you need the opposite — Halda must not run until the visitor accepts — use Option B.

Also note: on a live denial Halda keeps any already-rendered widgets visible while silencing their tracking and analytics. Suppression blocks new tracking and new widget injection, not the widgets already on the page. Halda is only fully absent (no widgets at all) when a denial is already known at page load, because Halda never boots in that case.

What you need to do for Option A

Nothing beyond running one of the recognized CMPs and making sure your consent categories are mapped correctly (see Consent category reference). Halda reads the standard cookies/events those platforms set.


Option B — Gate the script with your CMP (true opt-in / "don't fire until consent")

If Halda must not execute at all until the visitor affirmatively accepts, have your CMP withhold the Halda <script> tag until consent is granted. This is the most defensible approach for an opt-in requirement, it works on any CMP, and it requires no change on Halda's side — the script simply never runs until your CMP releases it.

The pattern is the same everywhere: mark the Halda script as belonging to the analytics/marketing category, and set its type so the browser doesn't execute it until the CMP rewrites it after consent.

Recommended: require an answer and block the page until the visitor responds

Recommendation. Gating the script keeps Halda from running before consent, but on its own it still lets a visitor scroll past the banner and keep browsing without ever answering. For a defensible opt-in posture, configure the banner as a blocking modal: grey out the page behind an overlay and prevent interaction with the site until the visitor accepts or rejects. Nothing loads, and no one browses, until there is a recorded choice.

Why it matters. This closes the un-answered-banner case. Under Option A an un-answered banner leaves Halda running (fail-open), which is correct for opt-out but wrong for opt-in. A blocking modal forces the choice up front, so Option B never has to rely on a visitor who simply ignored the banner.

How to turn it on. Enable your CMP's blocking-modal (consent-wall) mode rather than a dismissible banner. The setting names differ by platform:

OneTrust: set the banner interaction type so there is no implied consent (disable close-on-scroll and close-on-continue) and use a center-modal or full-page template. Keep Reject all on the first layer.

Cookiebot: choose the Dialog (overlay) layout instead of the slide-in Banner, and enable the option that blocks interaction until the visitor chooses.

CookieYes: use the Popup / Box layout with the page-blocking overlay enabled.

Osano: use a modal dialog and enable script and interaction blocking until a choice is stored.

If your CMP can't do this natively, render a full-viewport overlay yourself and remove it only after the CMP records a choice:

/* Grey out and lock the page until the visitor answers */
#halda-consent-overlay {
position: fixed; inset: 0;
background: rgba(0,0,0,.6);
z-index: 2147483646; /* below the banner, above everything else */
}
html.consent-pending { overflow: hidden; } /* block scroll */

// Drop the overlay only after a choice is stored (Cookiebot shown):
function clearGate(){
document.documentElement.classList.remove('consent-pending');
document.getElementById('halda-consent-overlay')?.remove();
}
window.addEventListener('CookiebotOnAccept', clearGate);
window.addEventListener('CookiebotOnDecline', clearGate);

One caveat. Several opt-in regimes require that rejecting is as easy as accepting and that visitors can still reach your privacy policy. Keep Accept all and Reject all equally prominent on the first layer, don't trap the visitor, and confirm the exact pattern with your privacy counsel. This guide is implementation advice, not legal advice.

OneTrust

<script
type="text/plain"
class="optanon-category-C0002"
src="https://YOUR-HALDA-EMBED-URL">
</script>

Use optanon-category-C0002 (Performance/Analytics) or optanon-category-C0004 (Targeting/Advertising) to match how you want consent scoped. Ensure OneTrust auto-blocking / re-scan is enabled so the tag is activated on accept.

Cookiebot

<script
type="text/plain"
data-cookieconsent="statistics"
src="https://YOUR-HALDA-EMBED-URL">
</script>

Use statistics or marketing. Cookiebot's auto-blocking must be enabled.

CookieYes

<script
type="text/plain"
data-cookieyes="cookieyes-analytics"
src="https://YOUR-HALDA-EMBED-URL">
</script>

Use cookieyes-analytics or cookieyes-advertisement.

Osano

Osano blocks scripts by its own classification. Add the Halda tag to the analytics/marketing classification in the Osano dashboard (or tag it per Osano's script-blocking instructions) so it is only released after consent.

Google Consent Mode / Google Tag Manager

If you deploy Halda through GTM, set the Halda tag to fire on a consent-granted trigger (e.g. gated on analytics_storage / ad_storage being granted) rather than on All Pages.


Which option should I use?

Your requirement

Use

US opt-out model — Halda may run until a visitor opts out

Option A alone is sufficient

Opt-in / strict — Halda must not fire until the visitor accepts

Option B (optionally with A as a backstop)

Defense in depth

Both — B withholds the script pre-consent, A reacts to a later mid-session denial


Geofencing California visitors

California is an opt-out state. Under the CCPA/CPRA a visitor does not have to opt in before analytics or advertising run. You have to offer a way to opt out and honor the Global Privacy Control (GPC) signal as a valid opt-out. Option A already does the GPC part for you: GPC reads as an unconditional deny, so Halda switches off for any California visitor whose browser sends the signal, with no geofencing required.

Why geofence at all. Two reasons. First, California expects California-specific notice, such as a "Your Privacy Choices" or "Do Not Sell or Share My Personal Information" link and banner, that you don't necessarily want to show every visitor. Second, California's wiretapping statute (CIPA) has driven a wave of litigation over trackers that fire before the visitor is notified, so some teams choose to gate trackers more tightly for California traffic even though the CCPA itself is opt-out. Geofencing lets you apply the right experience by region: a strict opt-in wall for the EU/EEA and UK, a California notice (and optional gating) for California, and the default opt-out behavior everywhere else.

The clean way: your CMP's geo rules. OneTrust, Cookiebot, CookieYes and Osano all support geolocation rule sets that swap the banner template and default consent state by region. Create a rule scoped to US-CA (California) that shows your California notice and, if you want tracker gating, applies the Option B script-gating pattern above. This is the recommended path because the geo decision and the consent gating live in one place, with no custom code to maintain.

If you need custom logic: geolocate at the edge. Read the visitor's region from your CDN or edge layer, which is faster and more reliable than a client-side lookup:

// Cloudflare Workers: request.cf.regionCode -> "CA"
// Fastly: geoip.region -> "CA"
// AWS CloudFront: CloudFront-Viewer-Country-Region header -> "CA"
// Vercel / Netlify: geo.region / context.geo.subdivision -> "CA"

const isCalifornia = country === "US" && region === "CA";

Then apply the right behavior. Branch on the flag at render time. For California, load the California notice and, if you're gating, keep the Halda script blocked until the visitor makes a choice (the Option B pattern). Otherwise fall through to your default:

<!-- Server/edge renders one of these based on isCalifornia -->

<!-- California: gated, with a "Your Privacy Choices" notice -->
<script type="text/plain" class="optanon-category-C0004"
src="https://YOUR-HALDA-EMBED-URL"></script>

<!-- Everywhere else: your default (Option A still honors GPC) -->
<script src="https://YOUR-HALDA-EMBED-URL"></script>

Don't rely on geofencing alone. IP geolocation is approximate. VPNs, corporate networks and mobile carriers routinely misplace visitors, and an IP address is itself personal information, so don't log or retain it for this purpose. Treat geofencing as routing to the right notice, and keep Option A running underneath as the backstop that honors GPC no matter where the request appears to come from. As with the rest of this guide, confirm your California approach with your privacy counsel.


Consent category reference

These are the categories Halda treats as an analytics/advertising grant or denial. Map the Halda script to one of these in your CMP.

CMP

Grant/Deny signal Halda reads

OneTrust

Groups C0002 (Analytics) / C0004 (Advertising) — :1 = grant, :0 = deny

Cookiebot

statistics / marketing — true = grant, false = deny

CookieYes

analytics / performance / advertisement — yes = grant, no = deny

Osano

ANALYTICS / MARKETING — ACCEPT = grant, DENY = deny

IAB TCF v2

Consent to any tracking purpose (2, 3, 4, 7, 8, 9, 10) = grant

Global Privacy Control

Browser navigator.globalPrivacyControl === true = unconditional deny

Grant takes precedence over deny: a partial accept (e.g. analytics denied but marketing accepted) reads as a grant.


How to verify it works

Test each state in your browser with DevTools open (Network + Console):

  1. Fresh visit, consent not yet answered — confirm Halda behaves per your chosen model (runs under Option A; does not load under Option B).
  2. Deny analytics/marketing in the banner — confirm no new request to /widgets/widget-to-display and no tracking event requests fire. Widgets already on the page are intentionally left in place (they simply stop tracking); they are not removed.
  3. Reload the page — confirm Halda stays off (the denial is remembered).
  4. Grant consent — confirm Halda comes back on and widgets reappear.
  5. Second tab — confirm a denial in one tab suppresses Halda in the other.

What Halda does not do yet 

  • No "wait N seconds for a banner" delay. Halda does not pause on load to wait for a slow banner before deciding.
  • Widgets are not torn down on a live denial. Suppression silences tracking and blocks new widget injection, but widgets already rendered stay on the page; only a denial detected before Halda boots prevents widgets entirely.
  • No Halda-side "strict mode" toggle. Affirmative-consent gating is achieved through your CMP (Option B), not a Halda account setting. No current plans to support this.