2.6 KiB
consent.ts
(no submodules)
Purpose
Implements the ConsentPolicy SPI bundled with @suaveplan/analytics-browser. The tracker calls policy.isAllowed(event) before any sampling, scrubbing, or queueing decision, so a false return short-circuits the entire pipeline and emits a drop event with reason consent. Two built-in policies ship with the package: AllowAllPolicy (default) and DoNotTrackPolicy (honours navigator.doNotTrack === "1"). Downstream consumers can implement their own policy — e.g. one that consults a stored cookie-banner preference — by implementing the interface from @suaveplan/analytics-browser/types.
Features
- Lazy navigator lookup — both policies are constructable in SSR / Node contexts where
navigatoris undefined; the policy simply permits the event in that case. - Zero state — both built-ins are stateless and reentrant.
- Strict equality on
"1"— matches the W3C Tracking Preference Expression spec; values"0"or"unspecified"permit tracking.
Usage: Basic
import { DoNotTrackPolicy } from "@suaveplan/analytics-browser/consent";
import { AnalyticsTracker } from "@suaveplan/analytics-browser/tracker";
const tracker = new AnalyticsTracker(transport, {
consentPolicy: new DoNotTrackPolicy(),
});
tracker.track("page_loaded"); // dropped if navigator.doNotTrack === "1"
Usage: Advanced
import type {
AnalyticsEvent,
ConsentPolicy,
} from "@suaveplan/analytics-browser/types";
class CookieBannerPolicy implements ConsentPolicy {
public constructor(private readonly read: () => "granted" | "denied") {}
public isAllowed(_event: AnalyticsEvent): boolean {
return this.read() === "granted";
}
}
API Reference
class AllowAllPolicy implements ConsentPolicy—isAllowed(event) → true.class DoNotTrackPolicy implements ConsentPolicy— returnsfalseifftypeof navigator !== "undefined" && navigator.doNotTrack === "1".
Implementation Notes
DoNotTrackPolicy reads navigator.doNotTrack on every call rather than caching at construction time. This is deliberate: the spec lets the user toggle the preference at runtime in some browsers (notably in private windows), and caching would freeze the decision at construction. The cost is a single property read per event — negligible compared with the JSON serialisation that follows on the happy path. Both classes pass their event argument with a leading underscore name to signal it is intentionally unused; lint rules permit underscore-prefixed unused parameters.