# Getting Started

> Install and set up Zest cookie consent on your website

Source: https://zest.freshjuice.dev/docs/getting-started/

## Installation

### CDN (Recommended)

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

```html
<!-- jsDelivr (full bundle with all 12 languages) -->
<script src="https://cdn.jsdelivr.net/npm/@freshjuice/zest"></script>

<!-- or unpkg -->
<script src="https://unpkg.com/@freshjuice/zest"></script>
```

### Single Language Bundle

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

```html
<!-- English only -->
<script src="https://cdn.jsdelivr.net/npm/@freshjuice/zest/dist/zest.en.min.js"></script>

<!-- German only -->
<script src="https://cdn.jsdelivr.net/npm/@freshjuice/zest/dist/zest.de.min.js"></script>

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

### npm (full build)

```bash
npm install @freshjuice/zest
```

```javascript
import '@freshjuice/zest';
```

The full build auto-initializes synchronously when the bundle is evaluated and exposes `window.Zest`. Interceptors (cookies, storage, scripts, network) install immediately so that any later `defer` or `async` tracker script is already gated. The UI mount (banner / widget) is deferred until `<body>` is available.

### 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:

```bash
npm install @freshjuice/zest
```

```javascript
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](/docs/examples/#headless-bring-your-own-ui) page for a full walkthrough.

## Basic Setup

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

```html
<!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://cdn.jsdelivr.net/npm/@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:

```html
<script
  src="https://cdn.jsdelivr.net/npm/@freshjuice/zest"
  data-position="bottom-right"
  data-theme="dark"
  data-accent-color="#ff6b35"
  data-policy-url="/privacy"
></script>
```

## Consent Categories

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

- [Configuration Options](/docs/configuration/) - Customize Zest behavior
- [Script Blocking](/docs/script-blocking/) - Learn about blocking modes
- [API Reference](/docs/api/) - Control Zest programmatically

