Treat consent as a lifecycle, not a page-load checkbox
A consent banner can change its answer after the page has loaded. Someone may accept analytics, continue browsing, and later withdraw permission in the same tab. If an integration only checks the banner once, its state can drift from the visitor's current choice. Wire both grant and withdrawal to the tracker, then test the full sequence rather than just the first page view.
WhoVisited exposes `window.whovisited.consent(allowed)` for that purpose. With `data-consent="required"` on the script, collection starts paused. Your consent manager remains responsible for deciding whether analytics is allowed; it should call the tracker whenever that decision changes. This API is a technical control, not a consent banner or legal compliance system.
<script async src="https://whovisited.net/tracker.js" data-site-id="YOUR_SITE_ID" data-consent="required"></script>Send both choices from your consent manager
Adapt the callback below to the consent manager installed on your site. The example's `analyticsAllowed` value is deliberately generic: it must come from the manager's final analytics category, not from a button click that merely opens or closes the banner. Call it after the tracker has loaded, or retain the latest choice and apply it when `window.whovisited` becomes available.
function applyAnalyticsChoice(analyticsAllowed) {
if (window.whovisited) {
window.whovisited.consent(analyticsAllowed === true);
}
}
// Call after the CMP has resolved or changed its analytics category.
applyAnalyticsChoice(cmpResult.analyticsAllowed);Do not treat a missing choice as approval. If the visitor rejects or withdraws analytics consent, call `consent(false)`. In the current tracker, that disables new tracking, clears queued events and the site's stored visitor and session identifiers, and clears the in-memory identifiers. If permission is later granted again in the same page, the tracker can resume and records a fresh page view with new identifiers.
Understand what browser privacy signals do here
Global Privacy Control (GPC) and Do Not Track (DNT) are browser signals, not a replacement for your consent manager. WhoVisited reads `navigator.globalPrivacyControl` and the legacy `navigator.doNotTrack === "1"` when the tracker initializes. If either indicates an opt-out, collection stays off for that page load, including when your code calls `consent(true)`. Reload after changing a browser privacy setting before testing its effect.
GPC's JavaScript property reflects a browser preference and is not supported in every major browser. MDN marks it as limited availability. DNT is deprecated and its specification was discontinued; WhoVisited still honors the `"1"` value for compatibility. Do not interpret an absent GPC signal or a DNT value other than `"1"` as proof that someone consented.
This describes the tracker's current behavior, not a legal conclusion about what a business must do. Review the privacy rules that apply to your site and configure your consent manager accordingly. A browser signal and a site-specific consent choice are separate inputs; neither should be silently rewritten to make analytics reports fuller.
Test grant, withdrawal, and a later grant
- In a clean browser profile with GPC off and DNT not set to "1", load a page with `data-consent="required"`. Before the CMP grants analytics permission, the Network panel should show no WhoVisited bootstrap or event request.
- Grant the analytics category in the CMP. Confirm the adapter calls `consent(true)` and that a page-view request can follow. Check the actual Network request and your configured site's allowed origin, rather than relying only on a console message.
- Withdraw analytics permission without navigating away. Confirm the adapter calls `consent(false)`, then navigate and trigger a custom event. No new tracking request should be initiated for those actions.
- Grant permission again and verify collection resumes with a new page view. The old visitor and session identifiers were cleared on withdrawal, so do not expect the earlier visitor record to continue.
- Repeat in a fresh profile with GPC enabled, then with DNT set to "1" where the browser supports it. Both should remain untracked even if the CMP callback says analytics is allowed.
A withdrawal cannot recall a request that was already sent over the network before the choice changed. The tracker discards a response if consent was revoked while an asynchronous request was in flight, but the browser cannot unsend bytes already delivered to the service. Keep the UI clear about when a choice takes effect, and do not describe withdrawal as erasing events already received.
Use the reversible control for a reversible choice
The tracker also exposes `window.whovisited.stop()`. In the current implementation this is a terminal stop for that page: it clears the queue and token, and future tracking calls remain disabled. A later `consent(true)` does not restart a stopped tracker. Use `consent(false)` for a visitor's reversible analytics withdrawal; reserve `stop()` for code that intentionally needs to shut down tracking for the rest of the page lifetime.
If no requests appear after consent is granted, check the actual callback value, the `data-consent` attribute, and whether a browser privacy signal is active. Then inspect the Network and Console panels for blocked script or API requests. The [WhoVisited installation guide](https://whovisited.net/guides/install-website-analytics) covers installation and event verification; the [Content Security Policy guide](/blog/verify-csp-for-whovisited-tracker) explains script and connection blocks.
Keep the integration honest about its limits
Browser support varies, storage can be unavailable, and a page cannot reverse an event already transmitted. Test the real CMP callback in the browsers your audience uses, including rejection, withdrawal and re-grant paths. WhoVisited can pause collection and clear its browser-side identifiers when told to do so; the site owner must connect that control to the correct consent category and explain the choice to visitors.
For browser behavior, see MDN's documentation for [`Navigator.globalPrivacyControl`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/globalPrivacyControl), the [`Sec-GPC` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Sec-GPC), and the deprecated [`Navigator.doNotTrack`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/doNotTrack). Those references describe the signals and their limitations; the integration behavior above is based on the current WhoVisited tracker source.