Extensions stop breaking your UI
No more support tickets when Consent-o-matic pushes an update that breaks your banner. Extensions interact with structured metadata, not your DOM.
Consent assistants, browsers, and regulators all depend on the data you produce. navigator.consent is the API that makes your compliance infrastructure machine-readable, turning your CMP into the authoritative data source the consent ecosystem relies on.
Users see the banner. They don’t see what’s behind it: vendor management across jurisdictions, legal-grade audit trails, real-time consent propagation to downstream processors, multilingual experiences that satisfy GDPR’s specificity requirement.
The proposed specification navigator.consent makes this work visible to the rest of the ecosystem. Your vendor declarations become structured data that consent assistants read directly. Your consent state becomes auditable by design. The CMP becomes the authoritative source the entire consent chain relies on.
Today, consent assistants reverse-engineer your DOM: scraping buttons, guessing vendor lists, injecting clicks. Every CMP update can break every extension. navigator.consent replaces this fragile scraping with a structured API: you declare your vendors and purposes, assistants read the metadata directly.
1// Check which regulations apply2const { regulations, jurisdiction } =3 await navigator.consent.getRegulations();4// → { regulations: ["gdpr", "eprivacy"], jurisdiction: "FR", … }56// Register your consent interface7const { registrationId } =8 await navigator.consent.registerInterface({9 vendor: "My CMP",10 versionIdentifier: "2.4.1",11 regulation: regulations[0] ?? "gdpr",12 jurisdiction: jurisdiction ?? "EU",13 });1415// Declare processing purposes with their legal basis16await navigator.consent.registerPurposes([17 {18 id: "analytics",19 name: "Analytics",20 legalBasis: "legitimate_interest",21 },22 {23 id: "advertising",24 name: "Advertising",25 legalBasis: "consent",26 },27 {28 id: "functional",29 name: "Functional",30 legalBasis: "legitimate_interest",31 },32]);3334// Declare vendors and link them to purposes35await navigator.consent.registerVendors([36 {37 id: "google-analytics",38 name: "Google Analytics",39 domain: "analytics.google.com",40 privacyPolicyUrl: "https://…/privacy",41 purposeIds: ["analytics"],42 },43 {44 id: "hotjar",45 name: "Hotjar",46 domain: "hotjar.com",47 privacyPolicyUrl: "https://…/privacy",48 purposeIds: ["analytics", "advertising"],49 },50]);5152// Signal the assistant before showing your banner53// Empty scope = general prompt; the assistant gets54// a chance to apply user preferences first55const snap = await navigator.consent.requestConsent();5657// If preferences were applied, skip your UI58if (Object.values(snap.purposes).some(v => v !== "unset")) {59 applyConsent(snap);60} else {61 showConsentBanner();62}No more support tickets when Consent-o-matic pushes an update that breaks your banner. Extensions interact with structured metadata, not your DOM.
When a consent assistant handles consent via the API, your full UI bundle (JS, CSS, fonts, images) never needs to load. At scale, this is measurable.
Every preference mutation is logged with provenance and timestamps. Compliance evidence is built into the protocol, not bolted on.
Consent assistants depend on your vendor and purpose declarations. The ecosystem reads from you, not around you.
A single API integration replaces N extension-specific workarounds. Every current and future consent assistant uses the same channel.
No more maintaining your own IP geolocation to guess which framework applies. The browser provides the regulation context directly via getRegulations(). One less moving part that can put you and your customers at risk.
navigator.consent is a transport layer. It does not replace your legal, compliance, or UX responsibilities.You present consent information and collect choices through your own interface. The API coordinates, it doesn’t mandate a UX.
You remain the system of record for consent evidence. The API adds a coordination channel, not a replacement.
You define consent scope (origin, domain, eTLD+1) and persistence policy. The browser does not override this.
Open registration model. No allow-lists, no attestation gates, no intermediary between you and your vendors.
All these methods run in DOM context. Extension-context scripts cannot call them. The browser enforces this boundary.
registerInterface()Declare your consent interface for the current page. Returns a registrationId for all subsequent operations.
registerVendors()Publish your vendor catalog: name, domain, privacy policy URL. Consent assistants read this instead of scraping.
registerPurposes()Publish processing purposes, each with a free-form id and human-readable name.
requestConsent()Signal the assistant before showing your consent UI. With an empty scope, it signals a general prompt (first-visit banner). With specific vendor or purpose IDs, it signals a contextual need (e.g. blocked embed). Either way, the assistant gets a chance to respond before you show your own UI.
updatePreferences()Sync already-collected preferences or push CMP-side updates. Fires an update event that assistants listen for.
getRegulations()Returns the browser's regulation context: applicable regulations, jurisdiction, and detection source. Shared method, available in both DOM and extension contexts.
The full API specification with types, methods, and behavior.
Machine-readable payload definitions for all API types.
A working polyfill for local experimentation.