Crumbie

Cookie consent components you'll actually want on your website.

Beautiful, accessible and fully editable cookie consent components for modern React applications.

npm install crumbie

Live demo

Try it yourself

Accept, decline, open settings, or reset consent. Everything is stored in localStorage on your device.

ConsentBlocked
NecessaryAllowed
PreferencesBlocked
AnalyticsBlocked
MarketingBlocked

ConsentGate preview

Analytics blocked — enable Analytics in settings.

Marketing blocked — enable Marketing in settings.

Installation

Drop in and own the code

Install the package or copy components into your project — just like shadcn/ui. No iframes, no third-party widgets, no lock-in.

bash
# pnpm
pnpm add crumbie

# npm
npm install crumbie
tsx
import {
  CrumbieProvider,
  CookieBanner,
  CookieSettings,
  CookieSettingsButton,
} from "crumbie"

export default function RootLayout({ children }) {
  return (
    <CrumbieProvider>
      {children}
      <CookieBanner />
      <CookieSettings />
      <CookieSettingsButton />
    </CrumbieProvider>
  )
}

Configuration

Pass configuration to the provider when you need a custom storage key, expiration period, or starting preferences. Necessary cookies always stay enabled.

tsx
<CrumbieProvider
  config={{
    storageKey: "crumbie-consent",
    expirationDays: 365,
    defaultPreferences: { analytics: false },
  }}
>
  {children}
</CrumbieProvider>

Gate content

Wrap analytics, marketing pixels, or any optional content in a consent gate. Its children render only after that category is allowed.

tsx
import { ConsentGate } from "crumbie"

<ConsentGate category="analytics">
  <Analytics />
</ConsentGate>

Read consent

Use a category hook when a component needs to make its own loading decision.

tsx
import { useConsentCategory } from "crumbie"

const analyticsEnabled = useConsentCategory("analytics")

if (analyticsEnabled) {
  // load analytics
}

Storage

Consent lives in localStorage only. Expired or invalid records are cleared safely, the banner reappears after expiration, and localStorage is accessed only after mount for SSR safety.

Need the full API? Read the documentation.