Every feature, free

A complete consent platform. Nothing locked behind a plan.

From the banner your visitors see to the receipts your DPO audits: here is everything ZenoCookieConsent does, and how.

The banner

Three layouts. One honest choice.

Show the banner as a bottom bar, a top bar or a centred modal, in your own colours. Whatever the layout, “Reject all” and “Accept all” share the exact same style, and the banner lives in a Shadow DOM so your CSS cannot break it and its CSS cannot leak into your site.

Bottom barThe default. Unobtrusive, always visible until the visitor chooses.
Centred modalA focused dialog with a backdrop, focus moved inside for keyboard users.
Top barFor layouts where the bottom of the screen is already busy.

Preferences & withdrawal

Granular choices, off by default.

The second layer lists each category your site actually uses (functional, analytics, marketing) with your own descriptions. Optional categories start switched off: pre-ticked boxes are not valid consent.

  • Only what you use. Categories you disable for a domain are never shown.
  • Persistent settings button. After a choice, a small cookie button (bottom left or right) reopens the preferences.
  • Your own link, too. Call Zeno.show() from a “Cookie settings” link in your footer.
  • Re-consent when it matters. Publish with “require re-consent” and returning visitors are asked again.

Script blocking engine

Nothing loads before consent. Not even by accident.

Change a tag's type to text/plain and add data-zeno. The browser will not run it; ZenoCookieConsent releases it, in document order, the moment its category is granted.

  • Scripts, iframes and images. External or inline, including type="module" via data-type.
  • Late arrivals too. A MutationObserver catches tags added after load, by the parser or by other scripts.
  • Several categories. data-zeno="analytics marketing" waits for both.
  • Google Consent Mode v2. Add data-gcm and Google tags get “denied” defaults immediately and updates on every choice.
<!-- Consent Mode v2 + forced language -->
<script src="https://consent.example.com/zeno.js"
        data-gcm data-lang="de"></script>

<script type="text/plain" data-zeno="marketing">
  fbq('init', '…');
</script>

<img data-zeno="analytics" alt=""
     data-src="https://pixel.example.com/p.gif">

<!-- Auto-filled cookie declaration table -->
<div data-zeno-declaration></div>

Proof of consent

A receipt for every decision.

GDPR Article 7(1) says you must be able to demonstrate consent. Every accept, reject and custom choice writes an append-only receipt to your database, validated against the domain's real configuration so the log can never claim consent for a category the site does not offer.

  • Pseudonymous by design. A random receipt id from the browser, a keyed hash of the truncated IP, no names or emails.
  • Tied to what was shown. Each receipt records the banner revision and language.
  • Abuse-resistant. Origin checks, payload limits and rate limiting on the public log endpoint.
  • Exportable. Filter and export the log; archives and backups go to your S3-compatible bucket.

Drafts & revisions

Publish like you mean it.

Edit a domain's texts, colours and cookie list as a draft. Publishing freezes everything into an immutable, numbered snapshot. The public API only ever serves the latest one, and every receipt points at the revision it was given against.

Changed what you process? Publish with “require re-consent” to bump the consent version, and returning visitors see the banner again.

Multi-tenant dashboard

One installation for every client.

Organizations own domains; people join organizations with a role. An agency runs all its clients from one server, and each client sees only its own sites.

A domain can also cover its subdomains, and an inactive domain is switched off instantly: no config served, no receipts accepted.

Roles apply per organization; one person can hold different roles in different organizations.
RoleCan
OwnerEverything, including deleting the organization
AdminManage domains and members
MemberEdit banner configuration, texts and cookies
ViewerRead-only, for example a DPO auditing consent logs

Languages

Speaks your visitors' language.

The banner picks the best match from the visitor's browser languages, falling back to the domain's default. Force a language with data-lang. The admin dashboard is translated too.

enEnglishReject all
deDeutschAlle ablehnen
daDanskAfvis alle
esEspañolRechazar todo
frFrançaisTout refuser
svSvenskaAvvisa alla
nbNorsk bokmålAvvis alle

Norwegian no and nn map to bokmål. Every text is editable per domain and language.

Under the hood

Small, fast and careful.

Zero-wait for returning visitors

The stored choice is read synchronously, so tags are released before any request to the consent server.

Injection-safe

Dashboard texts are inserted as text, never HTML; colours must be plain hex; privacy links must be http(s).

Fails closed

If the config cannot load, nothing extra is released beyond what a valid earlier choice allowed.

One first-party cookie

zeno_consent, strictly necessary, SameSite=Lax and Secure on HTTPS. That is all it stores.

Accessible

Real buttons and switches, labelled dialog, focus moved into the banner, visible focus rings, reduced-motion aware.

Cookie declaration

Drop <div data-zeno-declaration> into your privacy page and the published cookie list renders itself.

All of it. Free. On your server.

Install once, add as many domains as you like.