Integration GuidesCookie Consent Modal
Integration Guides

Cookie Consent Modal

Embed and configure the Neostra cookie consent modal (CPMP Modal) built with Svelte 5.

Cookie Consent Modal

The Neostra Cookie Consent Modal (CPMP Modal) is a lightweight, customizable consent banner built with Svelte 5. It handles cookie categorization, user preferences, Global Privacy Control (GPC) detection, and consent writeback to the Neostra platform.

Quick Start

Add a single script tag to your website to load and initialize the consent modal.

<script
  src="https://cdn.neostra.io/cpmp/modal.umd.latest.js"
  data-cp-id="your-consent-profile-id"
></script>

The script auto-initializes a CPMPModal singleton that:

  1. Loads configuration from the Neostra API
  2. Checks for existing consent cookies
  3. Detects Global Privacy Control signals
  4. Displays the consent banner if consent has not been recorded

The data-cp-id attribute is required. It maps to your consent profile configuration in the Neostra platform, which defines categories, cookie lists, UI text, and behavior.

Installation Options

Add the script tag before the closing </body> tag:

<!DOCTYPE html>
<html>
<head>
  <title>My Website</title>
</head>
<body>
  <!-- Your page content -->

  <script
    src="https://cdn.neostra.io/cpmp/modal.umd.latest.js"
    data-cp-id="your-consent-profile-id"
  ></script>
</body>
</html>

How It Works

Configuration

The modal loads its configuration from the Neostra API based on the data-cp-id. The configuration is managed through the Neostra platform UI but follows this structure:

Each cookie category has an ID, display name, description, and a required flag. The "necessary" category is always required and cannot be declined.

{
  "categories": [
    {
      "id": "necessary",
      "name": "Strictly Necessary",
      "description": "Essential for the website to function properly.",
      "required": true
    },
    {
      "id": "analytics",
      "name": "Analytics",
      "description": "Help us understand how visitors interact with the site.",
      "required": false
    },
    {
      "id": "marketing",
      "name": "Marketing",
      "description": "Used to deliver relevant advertisements.",
      "required": false
    },
    {
      "id": "functional",
      "name": "Functional",
      "description": "Enable enhanced functionality and personalization.",
      "required": false
    }
  ]
}

Components

The modal consists of two main components:

The ConsentManager handles reading and writing consent state.

Consent is stored as a browser cookie with configurable expiry. The consent cookie contains:

FieldDescription
uuidUnique subject identifier for consent tracking
categoriesObject mapping category IDs to boolean consent values
timestampISO 8601 timestamp of when consent was given or updated
versionConfiguration version to detect when re-consent is needed
{
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "categories": {
    "necessary": true,
    "analytics": true,
    "marketing": false,
    "functional": true
  },
  "timestamp": "2026-03-15T10:30:00Z",
  "version": "1.2"
}

API Writeback

When a user updates their consent, the modal submits the consent record to the Neostra API:

POST https://api.neostra.io/v1/consents
{
  "cpId": "your-consent-profile-id",
  "subjectId": "550e8400-e29b-41d4-a716-446655440000",
  "categories": {
    "necessary": true,
    "analytics": true,
    "marketing": false,
    "functional": true
  },
  "gpcDetected": false,
  "userAgent": "Mozilla/5.0 ...",
  "url": "https://www.example.com/page"
}

Event Handling

The modal fires a custom DOM event whenever consent is updated. Listen for this event to conditionally load scripts or activate features based on consent.

document.addEventListener("cpmp-consent-change", (event) => {
  const { categories, uuid } = event.detail;

  if (categories.analytics) {
    // Load analytics scripts
    loadGoogleAnalytics();
  }

  if (categories.marketing) {
    // Enable marketing pixels
    enableMarketingPixels();
  }

  console.log(`Consent updated for subject: ${uuid}`);
});

Global Privacy Control (GPC)

The modal automatically detects the Global Privacy Control signal (navigator.globalPrivacyControl). When GPC is enabled:

  • Non-essential cookie categories default to declined
  • The consent banner still appears but with non-essential categories pre-set to off
  • The GPC detection status is included in the consent writeback to the API

GPC detection respects the user's browser-level privacy preference as specified by the GPC specification. It does not prevent the user from manually opting in to categories.

Auto-Blocker

The auto-blocker script prevents third-party scripts from executing before consent is obtained. Add it before any other scripts on the page.

<head>
  <!-- Must be the first script -->
  <script src="https://cdn.neostra.io/cpmp/autoblocker.js"></script>

  <!-- These scripts will be blocked until consent is given -->
  <script src="https://www.googletagmanager.com/gtag/js?id=GA_ID"></script>
</head>
<body>
  <!-- Consent modal loads and manages script activation -->
  <script
    src="https://cdn.neostra.io/cpmp/modal.umd.latest.js"
    data-cp-id="your-consent-profile-id"
  ></script>
</body>

The auto-blocker works by:

  1. Intercepting script tags before they execute
  2. Matching scripts against known third-party domains in the configuration
  3. Holding blocked scripts until consent is obtained for the relevant category
  4. Releasing and executing scripts when the user grants consent

Modes

The default mode. Consent is persisted, writeback is enabled, and the modal respects existing consent cookies.

<script
  src="https://cdn.neostra.io/cpmp/modal.umd.latest.js"
  data-cp-id="your-consent-profile-id"
></script>

Do not use preview mode in production. It disables consent persistence and API writeback, meaning user preferences will not be saved.

Build Artifacts

FileFormatDescription
modal.umd.jsUMDVersioned build, suitable for production pinning
modal.umd.latest.jsUMDAlways resolves to the latest version
modal.es.jsES ModuleFor use with JavaScript bundlers
autoblocker.jsIIFEScript blocking, must load before other scripts