How do I build a kill switch to stop Adobe Analytics from sending data for specific pages or users?
Build the kill switch as a condition inside a Launch rule - a data element or a Custom Code check that a page-bottom rule (or every tracking rule) reads before it does anything else - rather than trying to remove the library or block the network request after the fact. A single shared data element, driven by a remote config value, a query parameter, or a consent-state check, lets you disable collection instantly without a code deploy, and lets you scope the disable to specific pages or user segments instead of an all-or-nothing switch.
Why this happens
Teams reach for a kill switch for a handful of recurring reasons: an internal-traffic exclusion (staff shouldn't pollute production analytics), a QA/staging environment that needs to behave identically to production except for actually sending data, a consent gate (don't collect until a user has opted in - which the site's existing consent banner already partially handles for ads/analytics categories, but a kill switch gives finer per-page control), or an emergency stop when a bad release is sending obviously wrong data and stopping collection is safer than shipping bad numbers for hours.
The reason this has to live inside Launch rather than as an afterthought is sequencing: once a beacon has already left the browser, there's no client-side way to un-send it. A kill switch only works if it's checked before the tracking call is made, which means it has to be part of the same rule logic that decides whether to track at all - not a separate mechanism layered on top.
Fix it
1. Create one shared "tracking enabled" data element that every tracking rule can check, rather than duplicating the same logic in each rule individually:
return (function () {
// Query param override, for QA/staging spot-checks: ?noTrack=1
var params = new URLSearchParams(window.location.search);
if (params.get('noTrack') === '1') return false;
// Internal-traffic exclusion, driven by a first-party cookie or flag
// your staff-login flow sets once (not a client-guessable value).
if (document.cookie.indexOf('webclat_internal=1') !== -1) return false;
// Environment check, in case a Launch environment is ever mis-pointed.
if (window.location.hostname.indexOf('staging.') === 0) return false;
return true;
})();2. Gate every tracking rule's action behind that data element, using a rule condition rather than checking it inside every custom-code action - a condition failure stops the rule before any tracking code runs at all, which is cleaner to audit than a scattered set of internal if checks:
Data Element: Tracking Enabled
Comparison: equals
Value: true3. For a page-level (rather than global) kill switch, extend the same data element to check the current path against a list, so specific pages - an internal admin tool, a password-reset flow with sensitive query parameters - never track regardless of who's visiting:
var excludedPaths = ['/admin', '/reset-password'];
if (excludedPaths.some(function (p) { return window.location.pathname.indexOf(p) === 0; })) {
return false;
}4. For a remotely toggleable emergency stop (turn off tracking without a deploy, during an incident), back the same data element with a value fetched from a small config endpoint or a Launch environment variable you can flip from the Launch UI directly, rather than only from code shipped in the page - a kill switch that requires a full deploy to activate is not fast enough for the emergency-stop use case it's meant to serve.
5. Respect the existing consent gate rather than working around it: this project's consent banner already default-denies analytics/ad tags until a visitor consents. A kill switch is for additional, more granular exclusions on top of that - internal traffic, specific pages, an incident stop - not a replacement for consent logic, and should never be used to collect data a user has explicitly declined.
How to verify it worked
- With the kill switch active (via the query param, the internal cookie, or the excluded path), open the AEP Debugger and confirm rules with the gating condition simply don't fire - not that they fire and then suppress the request afterward.
- Check the Network tab for the same test and confirm zero requests leave for your analytics or Edge Network domain - a rule that "doesn't fire" in the Debugger but still produces a beacon somewhere else in the codebase means another, ungated call path exists.
- With the kill switch inactive, repeat the same test and confirm tracking behaves exactly as it did before the kill switch was added - the goal is a clean off switch, not a change to normal behavior.
Illustrative, not a measured result: a support team debugging a live incident might use the query-param override to confirm a bad release's tracking calls stop cleanly within minutes, without waiting on a full deploy to disable them.
Related
- What's the reliable way to verify an Adobe Analytics tag fired correctly?
- How do I read a clicked element's data attributes in an Adobe Launch rule?
- Why do Adobe Analytics hits double up or fail on WebKit/Safari?