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
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | required | Child components |
translations | ConsentTranslations | English | Translation strings |
policyUrl | string | /cookies | URL to cookie policy page |
footerLinks | ConsentFooterLinks | - | Optional footer links |
onConsentChange | (consent: ConsentState) => void | - | Callback when consent changes |
showFloatingButton | boolean | true | Show 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
| Prop | Type | Default | Description |
|---|---|---|---|
tooltip | string | "Cookie Settings" | Tooltip text |
Features
- Fixed position: bottom-right corner
- Auto-hides when consent banner is open
- Shows tooltip on hover (uses
@elcto/uiTooltip 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>
);
}
Footer Links
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
| Prop | Type | Default | Description |
|---|---|---|---|
category | CookieCategory | - | Show status for specific category |
showOnlyWhenActive | boolean | false | Only show when cookies are active |
className | string | "" | Additional CSS classes |
showCount | boolean | false | Show count of active cookies |
labels | object | - | 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
| Prop | Type | Default | Description |
|---|---|---|---|
category | Exclude<CookieCategory, "essential"> | required | Cookie category required |
src | string | - | Script source URL |
children | string | - | Inline script content |
id | string | - | Script ID for deduplication |
strategy | "eager" | "lazy" | "eager" | Load strategy |
onLoad | () => void | - | Callback when loaded |
onError | (error: Error) => void | - | Callback on error |
scriptProps | ScriptHTMLAttributes | {} | 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
| Prop | Type | Default | Description |
|---|---|---|---|
src | string | - | Script source URL |
children | string | - | Inline script content |
id | string | - | Script ID for deduplication |
idPrefix | string | "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 |
scriptProps | ScriptHTMLAttributes | {} | 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
| Prop | Type | Default | Description |
|---|---|---|---|
category | Exclude<CookieCategory, "essential"> | required | Cookie category required |
children | ReactNode | required | Content when allowed |
fallback | ReactNode | - | 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:
- In production mode
- User has consented to functional cookies