Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Clonkie

A lightweight React library for managing cookies and consent—zero dependencies, zero bloat.

Warning

Using this library does not automatically make your application GDPR-compliant. It is your responsibility as a developer to implement a compliant cookie consent banner that meets the requirements of applicable data protection laws.

Quick start

import { CookieProvider, useConsent, useCookie, useCookieBanner } from "@jocraft2010/clonkie";

const SCOPES = [{ scope: "analytics" }, { scope: "marketing" }];

function App() {
  return (
    <CookieProvider scopes={SCOPES}>
      <Page />
      <Banner />
    </CookieProvider>
  );
}

function Page() {
  const analytics = useConsent("analytics");
  const [userId, setUserId] = useCookie<string>("user_id", "essential");
  return (
    <div>
      <p>Analytics: {analytics ? "on" : "off"}</p>
      <input value={userId ?? ""} onChange={(e) => setUserId(e.target.value)} />
    </div>
  );
}

function Banner() {
  const banner = useCookieBanner();
  if (!banner.isOpen) return null;
  return (
    <div>
      <button onClick={banner.acceptAll}>Accept</button>
      <button onClick={banner.rejectAll}>Reject</button>
    </div>
  );
}

Installation

npm install @jocraft2010/clonkie
yarn add @jocraft2010/clonkie
pnpm add @jocraft2010/clonkie
bun add @jocraft2010/clonkie

Peer dependencies: react ^18.0.0 || ^19.0.0. Make sure these are installed in your project.

API Reference

CookieProvider

Wraps your app with a consent context. Automatically injects an "essential" scope if not provided.

Props:

Prop Type Required
scopes CookieScope[] Yes
children ReactNode Yes

CookieScope

Field Type Default
scope string
path string "/"
maxAge number 31536000
domain string current domain
secure boolean true
sameSite "strict" | "lax" | "none" "lax"

useConsent(scope)

function useConsent(scope: string): boolean;

Returns true if the given scope is consented. The "essential" scope always returns true.

useCookie<T>(name, scope)

function useCookie<T>(name: string, scope: string): [T | undefined, (value: T) => boolean];

Returns a tuple of the current cookie value and a setter. The setter respects consent — if consent for the scope is denied, the cookie is deleted and the setter returns false (no-op).

useCookieBanner()

function useCookieBanner(): {
  isOpen: boolean;
  setBannerOpen: (open: boolean) => void;
  consent: Record<string, boolean>;
  setConsent: (consent: Record<string, boolean>) => void;
  acceptAll: () => void;
  rejectAll: () => void;
  applySelection: () => void;
};

Draft-based consent UI hook. Changes made via setConsent, acceptAll, or rejectAll are held in local state and only applied to the context when applySelection() is called.

useOnAcceptAll(fn)

function useOnAcceptAll(fn: () => void): void;

Registers a side-effect callback that fires when all scopes are accepted.

useOnRejectAll(fn)

function useOnRejectAll(fn: () => void): void;

Registers a side-effect callback that fires when all non-essential scopes are rejected.

useOnConsentChange(fn)

function useOnConsentChange(fn: (consent: Record<string, boolean>) => void): void;

Subscribes to any consent state change. The callback receives the full consent map.

Recipes

Load Google Analytics on consent

import { useConsent } from "clonkie";
import { useEffect } from "react";

function Analytics() {
  const consented = useConsent("analytics");
  useEffect(() => {
    if (consented) {
      // load gtag / GA script
    }
  }, [consented]);
  return null;
}

Persist user preferences with useCookie

const [theme, setTheme] = useCookie<"light" | "dark">("theme", "essential");

Since "essential" consent is always granted, the cookie is always available.

Persist consent to localStorage

import { useOnConsentChange } from "clonkie";

function ConsentLogger() {
  useOnConsentChange((consent) => {
    localStorage.setItem("consent", JSON.stringify(consent));
  });
  return null;
}

License

This project is licensed under MPL-2.0. Read the full License here

About

A lightweight React library for managing cookies and consent—zero dependencies, zero bloat.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages