Documentation
Design
Components
Cookie Consent

EccUtilsDesignCookieConsent Component

2.0.0-alpha.50
<ecc-utils-design-cookie-consent/>
EccUtilsDesignCookieConsent

Overview

The ecc-utils-design-cookie-consent component asks users for their consent to cookies (and similar storage, such as localStorage), per category, and lets them change their choice at any time. It works together with the compliance footer, which links to the preferences, and both read the same configuration, so an app adds them from configuration alone.

  • Banner on the first visit, with "Accept all", "Necessary only" (as prominent as accepting) and "Customize".
  • Preferences dialog with one switch per category; strictly necessary categories are always on.
  • Stored in the browser (localStorage, key ecc-cookie-consent), and asked again when the configured categories or the version change.
  • Checks for other code: hasConsent('analytics'), onConsentChange(...) and the ecc-cookie-consent-changed event on window.
⚠️

The component provides the mechanics only. Operators decide which categories their deployment needs and are responsible for the texts, the policies they link to, and for loading optional scripts only with consent (see Loading scripts with consent).

Without optional categories, nothing needs consent and the banner isn't shown (unless notice is set); the preferences still list the necessary category, e.g. for the footer's "Cookie Preferences" item.

Preview

This page shows the banner until you choose (stored only for this demo); the footer's "Cookie Preferences" opens the preferences again.

Usage

Add the component once per page, e.g. in the app's layout, next to the compliance footer:

layout.tsx
import EccUtilsDesignCookieConsent from '@elixir-cloud/design/react/cookie-consent';
import EccUtilsDesignComplianceFooter from '@elixir-cloud/design/react/compliance-footer';
import type { ComplianceConfig } from '@elixir-cloud/design/components/cookie-consent/index.js';
 
// e.g. from the deployment's runtime settings
const compliance: ComplianceConfig = {
  cookies: {
    version: '2026-10',
    policyUrl: '/cookies',
    categories: [
      { id: 'necessary', label: 'Necessary', required: true,
        description: 'Login and these choices.' },
      { id: 'analytics', label: 'Analytics',
        description: 'Anonymous usage statistics.' },
    ],
  },
  footer: {
    items: [
      { id: 'privacy-policy', action: { type: 'link', href: '/privacy' } },
      { id: 'contact', action: { type: 'mailto', email: 'support@example.org' } },
    ],
  },
};
 
export default function Layout({ children }) {
  return (
    <>
      {children}
      <footer>
        <EccUtilsDesignComplianceFooter config={compliance} />
      </footer>
      <EccUtilsDesignCookieConsent
        config={compliance}
        onEccCookieConsentChanged={(event) =>
          console.log(event.detail.consent.categories)
        }
      />
    </>
  );
}

Properties

PropertyTypeDefaultDescription
configComplianceConfig{}Shared compliance configuration; this component uses config.cookies. A new object with the same categories, version, storageKey and notice keeps the choices users haven't saved yet, so it may be created on every render.

Methods

MethodDescription
openPreferences()Opens the preferences. openCookiePreferences() does the same from anywhere on the page.

Events

Event NameReact Event NameDetail TypeDescription
ecc-cookie-consent-changedonEccCookieConsentChanged{ consent: CookieConsent }Fired when the user saved their choices. It doesn't bubble; saveConsent() fires the same event on window.

Configuration (config.cookies)

FieldTypeDescription
categoriesCookieCategory[]{ id, label, description?, required? }. A required "necessary" category is added if none is required.
versionstringVersion of the cookie policy; changing it asks users again.
policyUrlstringLink to the cookie policy (http(s) or relative), shown in the banner and the preferences.
noticebooleanShow the banner although there are no optional categories.
storageKeystringlocalStorage key, default ecc-cookie-consent.
textsPartial<CookieConsentTexts>Texts of the banner and the preferences, e.g. for translations: bannerTitle, bannerText, policyLink, acceptAll, rejectAll, customize, preferencesTitle, preferencesText, save, close, alwaysOn, embedConsent.

Changing a category's id or required, adding or removing a category, or changing version asks users again; changing texts or descriptions doesn't.

Loading scripts with consent

The functions below come from @elixir-cloud/design/components/cookie-consent/index.js (also exported by the package's main entry). Pass the same cookies configuration that the component uses.

import {
  hasConsent,
  onConsentChange,
  openCookiePreferences,
} from '@elixir-cloud/design/components/cookie-consent/index.js';
 
const loadAnalytics = () => { /* add the analytics script */ };
 
if (hasConsent('analytics', compliance.cookies)) loadAnalytics();
onConsentChange((consent) => {
  if (consent?.categories.analytics) loadAnalytics();
  // revoking consent: stop tracking and remove its cookies, or reload
}, compliance.cookies);
 
// e.g. from a link of your own
openCookiePreferences();
FunctionDescription
hasConsent(category, config?)Whether users consented to a category (required ones: always).
readConsent(config?)The stored CookieConsent, or null if users must be asked.
saveConsent(config, choices)Stores choices and fires ecc-cookie-consent-changed on window.
onConsentChange(listener, config?)Calls listener on every change for the storage key of config, in this page and in other tabs (with null if that consent was removed); returns a function to stop.
openCookiePreferences()Asks the page's component to open the preferences.

Notes for operators

  • List every category that your deployment uses, with a description users understand. Keep "Necessary" for what the site can't work without (e.g. login cookies); these need no consent under the GDPR and ePrivacy rules, but should be explained in the cookie policy.
  • Bump version when the cookie policy changes in a way users should see.
  • Provide the cookie policy (policyUrl, or a footer item) and load optional scripts only after hasConsent().
  • Consent is stored per browser and origin; it isn't sent to a server. If the browser can't store it, it applies to the current page only.

Released under Apache 2.0 License.

Copyright © 2023-2026 ELIXIR