Can you drop your CookieYes subscription and switch to Cookyay? This page gives you a factual answer — including the cases where the answer is no.
Feature data sourced from CookieYes.com, Cookiebot.com, and OneTrust.com pricing and feature pages. Last reviewed: June 2026. SaaS CMP pricing and features change frequently; verify before making decisions.
Sites serving Google personalized ads to EEA/UK/Swiss visitors must use a Google-certified CMP integrated with IAB Transparency and Consent Framework (TCF) v2.3. This is mandatory since January 16 2024; the TCF v2.2 → v2.3 migration deadline passed February 28 2026. Non-compliance results in Limited Ads (no personalization, no frequency capping — typically a >50% revenue impact for publishers).
Cookyay is not a Google-certified CMP and will never become one. IAB TCF registration is a permanent non-goal of this project (the vendor list management, consent string encoding, and certification process are designed for adtech platforms, not lean self-hosted libraries). If you run Google AdSense, Ad Manager, or AdMob and serve personalized ads to EEA/UK visitors, you need CookieYes, Cookiebot, or another certified CMP — not Cookyay.
Consent Mode v2 is not the same thing as Google CMP certification. Cookyay fully supports Consent Mode v2 (all four mandatory signals, correct load ordering, default-denied before GTM/GA4 loads). That is sufficient for sites using Google Analytics or Google Ads conversion tracking only — no ad serving. But CookieYes and Cookiebot are also Google-certified CMPs, which unlocks personalized ad inventory. These are different requirements; Cookyay covers one, not both.
Who this affects: AdSense monetized blogs, publisher sites using Ad Manager, apps with AdMob — any property earning revenue from personalized display ads served to EU/UK visitors. Sites with only Google Analytics, Google Ads conversion tracking, or no Google products at all are not affected by this wall.
The table below compares Cookyay v11 against CookieYes's free plan and paid plans (Basic / Pro, as of June 2026). CookieYes plan labels vary — "Free" is the no-credit-card tier; paid tiers unlock the features marked below. The most important caveat — the Google-certified CMP / IAB TCF wall — is covered in the section above.
| Feature | Cookyay (v11 / free/self-hosted) | CookieYes Free | CookieYes Paid |
|---|---|---|---|
| Banner & consent UI | |||
| Opt-in consent banner | ✓ Non-modal by default; modal flag available | ✓ | ✓ |
| Granular category toggles (necessary / functional / analytics / marketing) | ✓ Four built-in categories; services declared per-category | ✓ | ✓ |
| Preferences modal / second layer | ✓ Focus-trapped modal; keyboard-navigable; Escape does not record consent | ✓ | ✓ |
| Persistent "Cookie settings" re-open link |
✓ Auto-injected; can be disabled via
autoOpenLink: false
|
✓ | ✓ |
| Equal-prominence Accept / Decline buttons | ✓ Enforced in default CSS; both buttons same size, same contrast | ~ Layout varies by template | ~ Configurable; GDPR compliance is user's responsibility |
| Keyboard and screen-reader accessibility (WCAG 2.1 AA) |
✓ role="switch" toggles, focus trap,
axe-core CI gate
|
~ Not independently verified | ~ Not independently verified |
| Custom banner text / i18n |
✓ Every user-visible and ARIA string overridable via
strings config; English defaults.
v10: opt-in locale packs — de, fr,
es, it shipped as tree-shakeable ESM entry points (import de from 'cookyay/locales/de'); locale sets the lang attribute on the UI wrapper for correct
screen-reader pronunciation (WCAG 3.1.2). Each locale is independent — the default
bundle stays byte-unchanged. v11: RTL locale packs —
ar (Arabic) and he (Hebrew) added; pair with
dir: 'rtl' config field for correct bidirectional rendering.
|
✓ 170+ languages; 40+ auto-translated with browser-language auto-detection | ✓ 170+ languages; auto-detection |
v10 adds opt-in locale packs for the priority EU languages (German, French,
Spanish, Italian). v11 adds RTL packs for Arabic (ar) and Hebrew
(he); pair with the new dir: 'rtl' config field. Cookyay
does not auto-detect the visitor's browser language — the locale is selected by
the site owner and passed into config. CookieYes auto-detects and serves a
translated banner without configuration, and supports far more languages. If your
site has non-English visitors and you cannot supply your own strings, the 6-locale
v11 set may not be sufficient — consider
vanilla-cookieconsent v3 (20+ bundled
locales) as an alternative.
|
|||
| Banner theming / branding | ~ CSS custom properties exposed; no visual theme builder | ✓ | ✓ Visual editor |
| Bundle size (banner library) | ✓ <20 KB min+gzip (CI-gated); two-part bootstrap: <1 KB inline + deferred UI | ~ Loaded from CookieYes CDN; size not published | ~ Loaded from CookieYes CDN; size not published |
| Zero runtime dependencies | ✓ Vanilla TS; no npm runtime deps | N/A (hosted service) | N/A (hosted service) |
| Script & tracker blocking | |||
Declarative script blocking (type="text/plain" pattern) |
✓ Site owner declares every blocked script/iframe in HTML; bootstrap intercepts on load | ✓ | ✓ |
| Iframe blocking with placeholder |
✓ data-src pattern; placeholder prevents
layout collapse
|
✓ | ✓ |
| Re-execute scripts on consent grant |
✓ Node clone + re-append; idempotent (data-cookyay-state
guard)
|
✓ | ✓ |
| Auto-detection of known third-party scripts, pixels, and transport beacons |
✓ autoBlock: true intercepts known
third-party scripts, iframes, <img> beacon pixels (v6),
fetch()/sendBeacon() (v7), and (v8)
XMLHttpRequest calls to curated tracking endpoints — at runtime
without HTML changes; scanner CLI also emits copy-paste blocking snippets.
Caveats: Google tags (GTM/GA4) excluded (Consent Mode v2 instead); pre-consent
requests at page unload are dropped, not deferred; synchronous XHR
(open(..., false)) and same-origin-iframe XHR pass through;
document.write deferred; auto-block remains opt-in.
|
✓ Scans and auto-blocks known trackers without HTML changes | ✓ |
As of v8, the cookyay banner includes runtime auto-block via the
autoBlock: true config flag. When enabled, the banner intercepts
script, iframe, <img> beacon pixel,
fetch/sendBeacon (v7), and (v8)
XMLHttpRequest insertions and holds known
third-party services until the visitor consents — no changes to your page HTML
required. Google tags (GTM, GA4) are intentionally not blocked;
they degrade gracefully under Consent Mode v2 denied defaults instead.
Honest limits in v8: pre-consent requests fired at page unload
(pagehide/visibilitychange) are
dropped — no sessionStorage persistence, no future
replay; this is the legally correct no-consent-no-send outcome.
Synchronous XHR (open(..., false)) passes through
— intercepting it would block the main thread while the request is held
pre-consent. No curated tracker is sync-XHR-only; this gap is negligible in
practice.
Same-origin-iframe XHR is not covered — the
window.XMLHttpRequest replacement applies to the top-level context
only (consistent with existing DOM/transport scope limits). There is also a short
Phase-2 async escape window (a few ms while the lazy auto-block chunk loads) where
an async tracking call can escape — the same intrinsic bootstrap-first limit as
DOM interception, unchanged in v8. document.write interception
remains deferred; auto-block stays opt-in. The @cookyay/scanner CLI
auto-detects known third parties and emits a
suggestedBlocking[] array for declarative use (paste-ready HTML
snippets, one per blocking host). The scanner and runtime auto-block share the
same signature database — scan-time and run-time verdicts match. See
auto-detection workflow and the
runtime auto-block docs.
|
|||
| Google Consent Mode v2 | |||
| Consent Mode v2 default signals (all denied before any Google tag loads) | ✓ Synchronous inline bootstrap fires defaults before GTM/GA4 loads; correct ordering guaranteed | ✓ | ✓ |
All four mandatory signals (ad_storage,
analytics_storage, ad_user_data,
ad_personalization)
|
✓ | ✓ | ✓ |
| Consent Mode update on user action |
✓ gtag('consent','update',...) fired on
grant/deny
|
✓ | ✓ |
| Returning visitor: consent restored to Consent Mode pre-paint (no CLS flash) |
✓ Bootstrap reads cookyay_consent cookie
synchronously and restores signals
|
✓ | ✓ |
| Global Privacy Control (GPC) — CCPA | |||
Detect navigator.globalPrivacyControl |
✓ Detected synchronously in bootstrap, before banner renders | ✗ Not implemented as of June 2026 | ✗ Not implemented as of June 2026 |
| Honor GPC: suppress non-necessary scripts, store pre-denied consent record | ✓ GPC flag stored in consent record; all non-necessary categories denied | ✗ | ✗ |
| Visible GPC confirmation toast (CCPA Jan 2026 reg) | ✓ Toast displayed when GPC signal is detected, per updated CCPA regulations | ✗ | ✗ |
| Persistent "Do Not Sell or Share" link |
~ The auto-injected "Cookie settings" link opens the
preferences modal. The CCPA-exact wording ("Do Not Sell or Share My Personal
Information") can be set via reopenLabel config — not the default;
site owners opt in.
|
✓ Injected automatically | ✓ |
| Persistent honored GPC indicator (CCPA §7025(c)(6), 2026 regs) | ✓ v10: the always-present re-open link shows a persistent honored state (visual + ARIA label) when GPC is live and honored — the transient toast alone does not satisfy the 2026 "persistent indication" requirement | ✗ Not implemented as of June 2026 | ✗ |
| GPC honoring is a genuine differentiator for Cookyay. As of June 2026, vanilla-cookieconsent and CookieYes do not detect or act on the GPC signal. Cookyay is among the first open-source consent tools to implement the January 2026 CCPA persistent-indication requirement (v10). v10 also hardens GPC edge-case behavior under regression tests: GPC visitor grants analytics then withdraws (withdrawal record reflects the live GPC signal at write time), GPC signal removed mid-session, and GPC + later explicit grant re-firing Consent Mode update. | |||
| Consent record & storage | |||
| Consent stored in visitor's browser (cookie + localStorage) |
✓ cookyay_consent cookie (SameSite=Lax) +
localStorage mirror; schema: sv, t, pv, bv, c, gpc
|
✓ | ✓ |
| Consent record includes: timestamp, policy version, per-category choices, banner version | ✓ Webhook-ready schema from v1 | ~ Timestamp + categories stored | ✓ |
| Server-side / centralized consent log (queryable by the site owner) |
✗ No hosted log — Cookyay operates no infrastructure.
v10: optional outbound webhook — set
consent.webhook: 'https://your-endpoint' to POST the canonical
consent record (timestamp, policy version, per-category choices, GPC flag,
consentId, shown consent text) to your own backend on every consent
event. Fail-open by design: a blocked or offline endpoint never breaks the banner.
See Compliance limitations for a self-hosted
receiver recipe.
|
✓ Hosted consent log (30-day free; longer on paid) | ✓ Full consent log with export |
| Programmatic consent record export |
✓ v10:
exportConsent() returns the full record as JSON —
consentId, timestamp, policy version, per-category choices, GPC flag,
and the verbatim consent text shown at decision time (GDPR Art. 7(1)
demonstrability). Site owners wire a "Download my consent record" button from this
API.
|
~ Hosted dashboard export | ✓ Full export |
|
Important: GDPR Art. 7(1) places the burden of proof on the site
owner (the "controller"), not the visitor. A browser-local consent record is
evidence of the visitor's experience, but cannot be queried server-side when a
regulator asks "show me the consent record for user X." The v10 webhook bridges
this gap for sites that self-host a receiver — but the receiver is yours to build
and operate; Cookyay provides no hosted infrastructure. CookieYes's hosted log
handles this without additional setup. For sites where per-session auditability
matters, Cookyay recommends a self-hosted webhook receiver (e.g., a serverless
function writing to any database). See
Compliance limitations. Privacy note: enabling the webhook makes the site owner a data controller for consent-log events (the endpoint receives the consent record plus the visitor's implicit IP). Cookyay cannot ship a client-side signing secret — if integrity verification is needed, HMAC-verify the request shape server-side. |
|||
| Policy-version re-prompt (re-show banner when cookie policy changes) |
✓ Stored policyVersion compared on every
load; mismatch triggers re-prompt
|
✓ | ✓ |
| Consent record expiry | ✓ 12 months by default (configurable) | ✓ | ✓ |
| Withdrawal & re-prompt | |||
| Consent withdrawal (revoke previously granted categories) |
✓ Via preferences modal; Consent Mode update to
denied fired immediately
|
✓ | ✓ |
| Page-reload prompt on withdrawal (required for already-executed scripts) | ✓ "Reload required" prompt shown; already-loaded third-party scripts cannot be stopped mid-session without reload | ~ Behavior varies | ~ |
| Cookie scanner | |||
| Cookie / tracker discovery tool |
✓ @cookyay/scanner — Playwright-based CLI;
crawls your site locally, classifies cookies, emits ready-to-use config JSON with
confidence annotations
|
✓ Hosted SaaS scanner (scans from CookieYes servers) | ✓ More frequent auto-rescans on paid |
| Runs locally (no data sent to a third party during scan) | ✓ Playwright headless browser runs on your machine; nothing leaves your network | ✗ CookieYes servers crawl your public URL | ✗ |
| Scans pages behind authentication / local dev server |
✓ Scanner runs locally; can reach
localhost or authenticated pages
|
✗ Requires a public URL | ✗ |
| Automatic periodic re-scanning | ✗ Manual CLI run (schedule via your own CI/cron) | ~ Monthly on free | ✓ Frequent auto-rescans |
| Cookie categorization database |
✓ Open Cookie Database (460+ entries, Apache-2.0) +
curated ~60 known services (GA4, Google Ads, Meta Pixel, YouTube, reCAPTCHA,
Hotjar, Intercom, Stripe, Sentry, PostHog, and more).
v9: auto-refreshed weekly — the OCD source is pinned to a
specific upstream commit SHA and a scheduled CI job opens a review PR when the
upstream moves. Signature currency is readable via
import { SIGNATURES_DATE } from 'cookyay'
("signatures as of YYYY-MM-DD").
|
✓ Proprietary database | ✓ |
v9 — maintained, auto-refreshed, currency-visible signature DB.
The OCD source is pinned to a specific upstream commit SHA (stored in
.ocd-pin). A weekly scheduled CI workflow
(ocd-refresh.yml, Sunday 03:00 UTC) compares the pinned SHA to the
current upstream HEAD and opens a human-reviewed PR when the upstream has moved —
complete with an entry-count delta for easy review. Pin bumps are never
auto-merged: the human review gate catches upstream corruption or license changes.
The signature DB date is exposed as SIGNATURES_DATE (ISO string,
~25 B gzip) exported from the cookyay package, readable even in
declared-only (non-autoblock) installs. CI warns (but does not fail) when the pin
is older than 30 days, and hard-fails if the committed generated files
diverge from what prebuild would regenerate. CookieYes uses a
proprietary database with no public transparency into refresh cadence or currency.
|
|||
| Geo-targeting, TCF, dashboard | |||
| Geo-detection (show banner only to EU/CA visitors, hide from others) | ✗ Deliberate non-goal: strictest-everywhere posture; all visitors see the opt-in banner | ✓ | ✓ |
| IAB Transparency and Consent Framework (TCF) certification | ✗ Not in scope for Cookyay; TCF is designed for adtech platforms and requires vendor registration | ~ Partial; not IAB-certified CMP | ✓ (higher-tier plans) |
| Web dashboard (consent rate analytics, banner performance) | ✗ No hosted infrastructure; no dashboard | ✓ Basic | ✓ Full analytics |
| Multi-domain / multi-site management | ~ Each site deploys its own config; no shared management plane | ✓ | ✓ |
| Framework adapters (v11) | |||
| React / Next.js App Router |
✓ v11: @cookyay/react —
<CookyayBootstrap> (Server Component, guaranteed head order),
<CookyayInit> + useConsent() hook
(@cookyay/react/client), and getServerConsent() for
zero-DOM SSR reads (@cookyay/react/server). App Router only — Pages
Router deferred.
|
GTM tag template; Custom HTML workaround documented | GTM tag template; Custom HTML workaround documented |
| Vue 3 |
✓ v11: @cookyay/vue —
cookyayPlugin (install plugin) +
useConsent() composable. SSR-safe import; no server-side consent
helper in v11 (Nuxt SSR deferred).
|
✗ | ✗ |
v11 ships first-class adapters as separate npm packages with
cookyay as a peer dependency — the core bundle stays byte-unchanged.
Both adapters use only the public Cookyay API surface (init,
getConsent, onConsent,
cookyay:consent events). CMS plugins and no-code install paths remain
deferred.
|
|||
| Distribution & pricing | |||
| Cost | ✓ Free forever, no limits. Apache-2.0 open source. Serve from npm / jsDelivr (free CDN) or self-host. | Free tier: limited features, "Powered by CookieYes" branding | Paid plans from ~$10–$25/month/domain (pricing varies; verify at cookieyes.com) |
| Self-hostable script (no call-home, no third-party CDN required) |
✓ Serve dist/index.iife.js and
dist/bootstrap.js from your own server or any public CDN
|
✗ Script must load from CookieYes CDN | ✗ |
| No "Powered by" branding forced on visitors | ✓ | ✗ Free tier requires branding | ✓ |
| Open source / auditable code | ✓ Apache-2.0; full source on GitHub | ✗ Proprietary | ✗ |
| No data leaves the visitor's device to the library author | ✓ Zero telemetry by design | ✗ Consent data stored on CookieYes servers | ✗ |
Symbols: ✓ supported · ✗ not supported · ~ partial / conditional
Honesty is the point. Here are the things Cookyay deliberately does not do, each with a one-line "why". If any of these are hard requirements for your site, you should use a different tool.
cookyay:consent events to your own analytics tool (e.g.,
Plausible or
Fathom).
Why a deliberate non-goal: consent analytics require a hosted server — cookyay has no
infrastructure to operate and no intent to become a SaaS product.
cookyay_consent
cookie + localStorage). If a regulator asks "show me the consent record for user X on
date Y," Cookyay gives you no server-side answer — the data lives only in that user's
browser and is inaccessible to you unless you captured it. v10 adds an optional outbound
webhook and a programmatic exportConsent() API so you can forward records
to your own backend, but the backend is yours to build and host; Cookyay provides no
hosted infrastructure. CookieYes (paid) hosts this log for you.
Why a deliberate non-goal: no hosted infrastructure is a core design constraint; the
webhook + export path gives developers the data they need to build their own.
@cookyay/react adapter targets
Next.js App Router only — Pages Router is deferred. The
@cookyay/vue adapter has no server-side consent helper (Vue/Nuxt SSR
deferred — use getServerConsent from @cookyay/react/server if
you need SSR consent reading and are on Next.js). There is
no automated CMP config importer — vendor export formats are
undocumented and brittle; the migration guide provides
per-vendor manual checklists and the scanner is the one automatable step.
autoBlock: true flag intercepts known third-party
<script>, <iframe>,
<img> beacon pixels, fetch/sendBeacon, and
XMLHttpRequest calls to curated tracking endpoints. The following remain
deliberately out of scope:
Pre-consent requests at page unload are dropped, not deferred
— a sendBeacon or XHR call fired at pagehide/visibilitychange
before the user grants consent is silently dropped; no
sessionStorage persistence or cross-session replay (legally correct: no
consent = no send).
Synchronous XHR (open(..., false)) passes through
— holding a sync XHR pre-consent would block the main thread; no curated tracker is
sync-XHR-only.
Same-origin-iframe XHR is not covered
— the window.XMLHttpRequest replacement applies to the top-level browsing
context only. Phase-2 async escape window: a few ms while the lazy
auto-block chunk loads where an async tracker call can escape — the intrinsic
bootstrap-first limit.
document.write ad injection
— legacy DoubleClick/old AdSense, high page-breakage risk, deferred.
Auto-block stays opt-in.
Google tags (GTM/GA4) are intentionally not blocked — Consent Mode v2
degrades them gracefully instead.
<head>".
The runtime interception proxy is installed by the synchronous bootstrap snippet. Any
<script src> placed in the HTML before the bootstrap cannot
be blocked — the browser has already dispatched its fetch before the proxy exists. This
is an architectural limit of DOM-level interception. CookieYes can block scripts placed
anywhere on the page.
de), French (fr),
Spanish (es), and Italian (it). v11 adds Arabic
(ar) and Hebrew (he) RTL packs. These are tree-shakeable ESM
modules — the site owner imports and passes the desired pack; there is no automatic
browser-language detection. CookieYes auto-detects browser language and supports 170+
languages without configuration. If your site has visitors in languages outside these
six and you cannot supply your own strings config, Cookyay's locale
coverage may be insufficient.
Cookyay is not the only open-source option. Two libraries cover significant overlap and are worth knowing:
| Library | What it covers | What it lacks vs Cookyay | Best fit |
|---|---|---|---|
|
vanilla-cookieconsent v3
(orestbida) |
Banner UI, opt-in/opt-out per category, all Consent Mode v2 signals (7 signals,
superset of the 4 mandatory), onConsent/onChange
callbacks, declarative script blocking, 20+ bundled locales, ARIA-accessible. ~24
KB min+gzip.
|
No GPC signal detection or honoring. No CLI scanner. No two-part bootstrap (Consent Mode defaults ordering is user's responsibility). Slightly over the 20 KB budget Cookyay targets. | Sites that need built-in multi-language support and are comfortable handling Consent Mode load ordering themselves. The most mature and widely deployed open-source option. |
| Klaro! | Per-service script blocking, i18n with bundled translations, declarative config, actively maintained. | No Google Consent Mode v2 support. No GPC honoring. No CLI scanner. No two-part bootstrap. Config schema is more verbose than Cookyay's. | Sites that need granular per-service blocking with rich translations but don't rely on Google Analytics/Ads (where Consent Mode v2 matters for revenue signal quality). |
If you only need banner UI + Consent Mode v2 and don't care about GPC or a local scanner,
vanilla-cookieconsent v3 is the more mature choice — it has a larger user
base, more themes, and 20+ built-in translations (vs Cookyay's 4-locale v10 packs).
Cookyay's differentiators are: the two-part bootstrap (Consent Mode ordering handled
automatically), GPC detection, honoring, and persistent indicator (unique among these
three as of June 2026), the local CLI scanner (runs against localhost and authenticated
pages, with auto-detection of ~60 known third parties and copy-paste blocking snippets),
runtime auto-block via autoBlock: true (v8 — intercepts known third-party
scripts, iframes, <img> beacon pixels,
fetch/sendBeacon, and XMLHttpRequest calls to
curated endpoints without HTML changes; same signature database as the scanner; honest
about unload-drop behavior, the Phase-2 async escape window, synchronous-XHR pass-through,
and same-origin-iframe XHR not covered; document.write still deferred;
auto-block opt-in), a maintained, auto-refreshed signature database (v9)
with weekly OCD pin-bumps via reviewed PRs and a consumer-readable currency date
(SIGNATURES_DATE), v10 EU locale packs
(de/fr/es/it, tree-shakeable, default
bundle byte-unchanged), v10 consent export API (exportConsent()) and optional
outbound webhook, and the strictest-everywhere posture as an explicit design principle
rather than an option.
autoBlock: true (v8) and known third-party scripts, iframes,
<img> beacon pixels, fetch/sendBeacon, and
XMLHttpRequest calls to curated tracking endpoints are intercepted
automatically. The bootstrap snippet must be first in <head> — the
same requirement that already exists for Consent Mode v2 ordering. Set
debug: true to get a console warning if any known tracker loaded before the
bootstrap (v6 install-order diagnostic). Note: pre-consent requests at page unload are
dropped, not deferred — this is the legally correct outcome. Synchronous XHR passes
through unconditionally (would block the main thread while held).
import { SIGNATURES_DATE } from 'cookyay'.
import de from 'cookyay/locales/de') that cover the priority
EU enforcement languages. The locale sets the lang attribute on the Cookyay
UI wrapper for correct screen-reader pronunciation (WCAG 3.1.2).
consent.webhook
config) to POST every consent event to your own backend. Or call
exportConsent() programmatically to get the full JSON record (including the
verbatim shown consent text, for GDPR Art. 7(1) demonstrability). The backend is yours
to operate — Cookyay provides the data, not the storage.
<head>" (for example because a CMS injects GTM unconditionally at the
top of the page), auto-block cannot help for those scripts. CookieYes does not have this
load-order constraint.
strings config, Cookyay's locale
coverage will not meet your needs. CookieYes auto-detects browser language and supports
170+ languages without any configuration.
The comparison above tells you whether to switch. The migration guide tells you how — with per-vendor checklists covering script removal, category remapping, the scanner step, CSP updates, and the consent-cookie name change that re-prompts returning visitors.