Getting Started

Install and set up Zest cookie consent on your website

Installation

The easiest way to add Zest to your website is via CDN:

<!-- unpkg (full bundle with all 12 languages) -->
<script src="https://unpkg.com/@freshjuice/zest"></script>

<!-- or jsDelivr -->
<script src="https://cdn.jsdelivr.net/npm/@freshjuice/zest"></script>

Single Language Bundle

For smaller bundle size (~10KB vs ~16KB gzipped), use a single-language build:

<!-- English only -->
<script src="https://unpkg.com/@freshjuice/zest/dist/zest.en.min.js"></script>

<!-- German only -->
<script src="https://unpkg.com/@freshjuice/zest/dist/zest.de.min.js"></script>

<!-- Available: en, de, es, fr, it, pt, nl, pl, uk, ru, ja, zh -->

npm (full build)

npm install @freshjuice/zest
import '@freshjuice/zest';

The full build auto-initializes on DOMContentLoaded and exposes window.Zest.

npm (headless — bring your own UI)

If you want to run the consent engine without Zest's built-in UI (e.g. to render your own banner in React/Vue), use the headless entry:

npm install @freshjuice/zest
import Zest from '@freshjuice/zest/headless';

Zest.init({
  mode: 'safe',
  callbacks: {
    onAccept: (consent) => console.log('Accepted:', consent)
  }
});

The headless build (~11KB gzipped) ships without the Shadow DOM UI, without translations, and does not auto-initialize or set window.Zest. You call Zest.init(config) explicitly and render your own consent surface. See the Examples page for a full walkthrough.

Basic Setup

Add the script before any tracking scripts you want to block:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My Website</title>

  <!-- Zest configuration (optional) -->
  <script>
    window.ZestConfig = {
      policyUrl: '/privacy-policy'
    };
  </script>

  <!-- Load Zest BEFORE tracking scripts -->
  <script src="https://unpkg.com/@freshjuice/zest"></script>

  <!-- These will be auto-blocked until consent -->
  <script async src="https://www.googletagmanager.com/gtag/js?id=GA-XXXXX"></script>
</head>
<body>
  <!-- Your content -->
</body>
</html>

How It Works

  1. On page load, Zest checks if the user has already made a consent decision
  2. If no decision, the consent banner is displayed
  3. Known tracking scripts are automatically blocked (in safe mode or higher)
  4. When user consents, blocked scripts are executed and cookie/storage operations are replayed
  5. A floating widget appears so users can change their preferences later

Configuration via Data Attributes

You can also configure Zest using data attributes on the script tag:

<script
  src="https://unpkg.com/@freshjuice/zest"
  data-position="bottom-right"
  data-theme="dark"
  data-accent-color="#ff6b35"
  data-policy-url="/privacy"
></script>

Zest uses four consent categories:

Category Default Description
Essential Always ON Strictly-necessary storage that cannot be disabled — login sessions, security tokens, shopping cart, the consent decision itself, and preferences the user has explicitly set on this site (language switcher, theme toggle). Exempt from consent under ePrivacy Art. 5(3).
Functional OFF Optional comfort features that enhance the experience without being strictly necessary — live-chat widgets, embedded video player preferences, third-party comment systems, recently-viewed lists.
Analytics OFF Usage tracking (Google Analytics, Plausible, etc.).
Marketing OFF Advertising and remarketing (Facebook Pixel, Google Ads, etc.).

Why language/theme aren't "Functional". A common mistake is to bucket UI-language and theme toggles under the optional functional category. If the user actively chose them on this site (clicked the language switcher, flipped to dark mode), they qualify as strictly-necessary under ePrivacy Art. 5(3) — the user explicitly requested that behaviour. Don't ask consent for honouring it. Reserve the functional toggle for things that are genuinely optional comfort, like a live-chat embed loaded from a third-party origin.

Next Steps