Skip to main content

Components

The cookies-consent package provides two main components for cookie consent management.

ConsentProvider

The main provider component that wraps your app and manages consent state.

Props

PropTypeDefaultDescription
childrenReactNoderequiredChild components
translationsConsentTranslationsEnglishTranslation strings
policyUrlstring/cookiesURL to cookie policy page
footerLinksConsentFooterLinks-Optional footer links
onConsentChange(consent: ConsentState) => void-Callback when consent changes
showFloatingButtonbooleantrueShow floating cookie button

Usage

import { ConsentProvider, defaultTranslations } from "@elcto/cookies-consent";

function App() {
return (
<ConsentProvider
translations={defaultTranslations.en}
policyUrl="/en/cookies"
footerLinks={{
privacyUrl: "/en/privacy",
contactUrl: "/contact",
imprintUrl: "/imprint",
}}
onConsentChange={(consent) => {
console.log("Consent updated:", consent);
}}
showFloatingButton={true}
>
<YourApp />
</ConsentProvider>
);
}

ConsentBanner

The modal component that displays cookie consent options. This is automatically rendered by ConsentProvider when needed.

Features

  • Main View: Shows title, description, and action buttons

    • "Essential Only" - Accept only essential cookies
    • "Accept All" - Accept all cookie categories
    • "Customize" - Open detailed settings
  • Customize View: Shows all cookie categories with toggles

    • Essential (always on, cannot be disabled)
    • Functional (toggleable)
    • Statistics (toggleable)
    • Marketing (toggleable)
    • Each category shows its cookies with name, purpose, and duration

Styling

The banner uses CSS variables from @elcto/ui for consistent theming:

  • --bg-card - Modal background
  • --border-default - Border color
  • --brand - Brand/accent color
  • --text-primary - Primary text color
  • --text-secondary - Secondary text color

CookieSettingsButton

A floating button in the bottom-right corner that opens the consent banner.

Props

PropTypeDefaultDescription
tooltipstring"Cookie Settings"Tooltip text

Features

  • Fixed position: bottom-right corner
  • Auto-hides when consent banner is open
  • Shows tooltip on hover (uses @elcto/ui Tooltip component)
  • Animated hover effect (scale + shadow)

Usage

The button is automatically rendered by ConsentProvider if showFloatingButton is true. You can also use it standalone:

import { CookieSettingsButton } from "@elcto/cookies-consent";

function Footer() {
return (
<footer>
{/* Other footer content */}
<CookieSettingsButton tooltip="Cookie Settings" />
</footer>
);
}

The consent banner supports optional footer links displayed below the action buttons.

Configuration

const footerLinks = {
privacyUrl: "/privacy", // Privacy policy
contactUrl: "/contact", // Contact page
imprintUrl: "/imprint", // Imprint/Legal
};

Display

Links are shown with vertical separators:

Privacy | Contact | Imprint
  • Links change to brand color on hover
  • All links open in new tab
  • Only provided links are shown (all are optional)

CookieStatusIndicator

A visual indicator component showing cookie consent and detection status.

Props

PropTypeDefaultDescription
categoryCookieCategory-Show status for specific category
showOnlyWhenActivebooleanfalseOnly show when cookies are active
classNamestring""Additional CSS classes
showCountbooleanfalseShow count of active cookies
labelsobject-Custom label strings

Usage

import { CookieStatusIndicator } from "@elcto/cookies-consent";

// Show overall status
<CookieStatusIndicator />

// Show status for specific category
<CookieStatusIndicator category="statistics" />

// Show only when cookies are active
<CookieStatusIndicator showOnlyWhenActive showCount />

// Custom labels
<CookieStatusIndicator
labels={{
active: "Running",
inactive: "Stopped",
allowed: "Permitted",
blocked: "Disabled",
}}
/>

Status Colors

  • Green: Cookies are active
  • Yellow: Category is allowed but no cookies detected yet
  • Gray: Category is blocked/inactive

ConditionalScript

Conditionally loads scripts based on cookie consent. Only loads when the required category is allowed.

Props

PropTypeDefaultDescription
categoryExclude<CookieCategory, "essential">requiredCookie category required
srcstring-Script source URL
childrenstring-Inline script content
idstring-Script ID for deduplication
strategy"eager" | "lazy""eager"Load strategy
onLoad() => void-Callback when loaded
onError(error: Error) => void-Callback on error
scriptPropsScriptHTMLAttributes{}Additional script attributes

Usage

import { ConditionalScript } from "@elcto/cookies-consent";

// Load external script when statistics is allowed
<ConditionalScript
category="statistics"
src="https://analytics.example.com/script.js"
onLoad={() => console.log("Analytics loaded")}
/>

// Inline script for marketing
<ConditionalScript category="marketing" strategy="lazy">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
`}
</ConditionalScript>

Load Strategies

  • eager: Loads immediately when category is allowed
  • lazy: Waits for user interaction (scroll, mouse move, touch, keydown) before loading

EssentialScript

Loads essential scripts immediately without waiting for consent. Essential scripts are always allowed as they are required for basic functionality.

Props

PropTypeDefaultDescription
srcstring-Script source URL
childrenstring-Inline script content
idstring-Script ID for deduplication
idPrefixstring"essential"ID prefix for auto-generated IDs
strategy"eager" | "lazy""eager"Load strategy
onLoad() => void-Callback when loaded
onError(error: Error) => void-Callback on error
scriptPropsScriptHTMLAttributes{}Additional script attributes

Usage

import { EssentialScript } from "@elcto/cookies-consent";

// Load essential security script immediately
<EssentialScript
src="https://security.example.com/verify.js"
onLoad={() => console.log("Security script loaded")}
/>

// Essential inline script
<EssentialScript>
{`window.CSRF_TOKEN = "${csrfToken}";`}
</EssentialScript>

ConditionalContent

Conditionally renders content based on cookie consent. Shows fallback when category is not allowed.

Props

PropTypeDefaultDescription
categoryExclude<CookieCategory, "essential">requiredCookie category required
childrenReactNoderequiredContent when allowed
fallbackReactNode-Fallback content when blocked

Usage

import { ConditionalContent } from "@elcto/cookies-consent";

// Show YouTube embed only if marketing cookies are allowed
<ConditionalContent
category="marketing"
fallback={
<div className="placeholder">
<p>Enable marketing cookies to view this video</p>
<button onClick={openCookieSettings}>
Manage Cookie Settings
</button>
</div>
}
>
<iframe src="https://www.youtube.com/embed/..." />
</ConditionalContent>

// Show analytics dashboard only if statistics is allowed
<ConditionalContent category="statistics">
<AnalyticsDashboard />
</ConditionalContent>

Analytics Components

Pre-built analytics integrations that automatically respect cookie consent. These components only load when the user has consented to the statistics category.

GoogleAnalytics

Loads Google Analytics 4 with consent.

import { GoogleAnalytics } from "@elcto/cookies-consent";

// In your layout or app component
<GoogleAnalytics measurementId="G-XXXXXXXXXX" />

Environment Variable: NEXT_PUBLIC_GA_MEASUREMENT_ID

FacebookPixel

Loads Facebook Pixel with consent.

import { FacebookPixel } from "@elcto/cookies-consent";

<FacebookPixel pixelId="123456789" />

Environment Variable: NEXT_PUBLIC_FB_PIXEL_ID

Hotjar

Loads Hotjar with consent.

import { Hotjar } from "@elcto/cookies-consent";

<Hotjar siteId="1234567" />

Environment Variable: NEXT_PUBLIC_HOTJAR_SITE_ID

Matomo

Loads Matomo/Piwik analytics with consent.

import { Matomo } from "@elcto/cookies-consent";

<Matomo url="https://analytics.example.com" siteId="1" />

Environment Variables: NEXT_PUBLIC_MATOMO_URL, NEXT_PUBLIC_MATOMO_SITE_ID

Plausible

Loads Plausible Analytics with consent.

import { Plausible } from "@elcto/cookies-consent";

<Plausible domain="example.com" />

Environment Variable: NEXT_PUBLIC_PLAUSIBLE_DOMAIN

Usage in Apps

Add analytics to your layout (inside ConsentProvider):

import { ConsentProvider, GoogleAnalytics } from "@elcto/cookies-consent";

function RootLayout({ children }) {
const gaId = process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID;

return (
<ConsentProvider translations={...} policyUrl={...}>
{gaId && <GoogleAnalytics measurementId={gaId} />}
{children}
</ConsentProvider>
);
}

Sentry Integration

Sentry error tracking should respect functional cookie consent. The recommended approach is to check consent in your Sentry client config:

// sentry.client.config.ts
import * as Sentry from "@sentry/nextjs";

function isSentryAllowed(): boolean {
if (typeof window === "undefined") return true;
try {
const stored = localStorage.getItem("elcto_cookie_consent");
if (!stored) return false;
const consent = JSON.parse(stored);
return consent?.categories?.functional === true;
} catch {
return false;
}
}

Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
enabled: process.env.NODE_ENV === "production" && isSentryAllowed(),
// ... other config
});

This ensures Sentry only runs when:

  1. In production mode
  2. User has consented to functional cookies