Thanks to visit codestin.com
Credit goes to www.openconsent.dev

Open Consent
v0.1.0MIT License

Documentation

A full-featured, GDPR-compliant cookie consent solution with traceability support, distributed via shadcn/ui registry.

Getting Started

Get up and running with the Open Cookie Consent Banner in minutes. This component is distributed via the shadcn/ui registry system for easy installation.

Quick Install
terminal
npx shadcn@latest add https://openconsent.dev/r/cookie-consent.json

This command will install all necessary files and dependencies automatically.

Note: This project is open source for transparency and community contributions. The primary way to use this component is through the shadcn/ui registry.

Installation

Via Registry (Recommended)

terminal
npx shadcn@latest add https://openconsent.dev/r/cookie-consent.json

The registry automatically includes all necessary files and dependencies.

Manual Installation

If you want to fork, customize, or contribute to the project:

  1. Clone the repository from GitHub
  2. Copy the components/cookie-consent directory to your project
  3. Install required shadcn/ui components:
terminal
npx shadcn@latest add button dialog switch card label accordion

Dependencies

buttondialogswitchcardlabelaccordion

Configuration

Wrap your app with CookieConsentProvider and configure the banner behavior.

Basic Setup

app/layout.tsx
1import {
2 CookieConsentProvider,
3 CookieBanner,
4 CookieSettings,
5 CookieTrigger,
6} from "@/components/cookie-consent"
7
8export default function App({ children }) {
9 return (
10 <CookieConsentProvider
11 config={{
12 consentVersion: "1.0.0",
13 privacyPolicyUrl: "/privacy",
14 traceability: {
15 enabled: true,
16 endpoint: "/api/consent",
17 },
18 }}
19 >
20 {children}
21 <CookieBanner />
22 <CookieSettings />
23 <CookieTrigger />
24 </CookieConsentProvider>
25 )
26}

Configuration Options

OptionTypeDefaultDescription
consentVersionstringRequiredVersion of your privacy policy
expirationDaysnumber365Days until consent expires
privacyPolicyUrlstring-Link to privacy policy
positionstring"bottom"Banner position
traceabilityobject-Audit trail configuration

Banner Positions

bottomtopbottom-leftbottom-right

Components

CookieConsentProvider
Context provider that manages consent state. Must wrap your application.
tsx
<CookieConsentProvider config={config}>
{children}
</CookieConsentProvider>
CookieBanner
The main consent banner displayed to users who haven't consented.
tsx
<CookieBanner className="custom-class" />

✓ Animated entrance/exit • ✓ Accept All / Reject All / Customize

✓ Privacy policy link • ✓ Responsive design • ✓ Accessible

CookieSettings
Modal dialog for granular consent preferences.
tsx
<CookieSettings className="custom-class" />
CookieTrigger
Button/link to reopen settings after consent has been given.
tsx
1// Default
2<CookieTrigger />
3
4// Custom text
5<CookieTrigger>Manage Cookies</CookieTrigger>
6
7// As a link
8<CookieTrigger asChild>
9 <a href="#">Cookie Preferences</a>
10</CookieTrigger>
ConsentScript
Declarative component for loading scripts based on consent.
tsx
1<ConsentScript
2 id="google-analytics"
3 src="https://www.googletagmanager.com/gtag/js?id=GA_ID"
4 category="analytics"
5 onLoad={() => console.log("GA loaded")}
6 onRevoke={() => {
7 // Clean up GA cookies
8 }}
9/>

Hooks

useCookieConsent
Main hook for accessing consent state and actions.
use-cookie-consent.ts
const {
state,
isBannerVisible,
isSettingsOpen,
acceptAll,
rejectAll,
updateConsent,
openSettings,
closeSettings,
hasConsent,
resetConsent,
} = useCookieConsent()
useConsentValue
Check if a specific category has consent.
tsx
1const hasAnalyticsConsent = useConsentValue("analytics")
2
3useEffect(() => {
4 if (hasAnalyticsConsent) {
5 initializeGA()
6 }
7}, [hasAnalyticsConsent])
useConsentScript
Programmatically manage script loading based on consent.
tsx
1const { isLoaded, isLoading, hasConsent, error } =
2 useConsentScript({
3 id: "intercom",
4 src: "https://widget.intercom.io/widget/APP_ID",
5 category: "preferences",
6 })

Script Management

Automatically load and unload third-party scripts based on user consent.

Google Analytics

analytics.tsx
1<ConsentScript
2 id="gtag"
3 src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXX"
4 category="analytics"
5 onLoad={() => {
6 window.dataLayer = window.dataLayer || []
7 function gtag(...args) {
8 window.dataLayer.push(args)
9 }
10 gtag("js", new Date())
11 gtag("config", "G-XXXXXX")
12 }}
13/>

Facebook Pixel

marketing.tsx
1<ConsentScript
2 id="facebook-pixel"
3 category="marketing"
4 content={`
5 fbq('init', 'PIXEL_ID');
6 fbq('track', 'PageView');
7 `}
8 onRevoke={() => {
9 // Clean up FB cookies
10 }}
11/>

Best Practices

  • Always provide onRevoke - Clean up cookies, globals, and event listeners
  • Use unique ids - Prevents duplicate script loading
  • Test revocation - Verify cleanup works correctly
  • Use lazyOnload for non-critical scripts

Traceability

Consent traceability is essential for GDPR compliance. Every consent action generates a record that can be sent to your backend API.

Setup

app/layout.tsx
1<CookieConsentProvider
2 config={{
3 consentVersion: "1.0.0",
4 traceability: {
5 enabled: true,
6 endpoint: "/api/consent",
7 headers: {
8 "X-API-Key": process.env.NEXT_PUBLIC_API_KEY,
9 },
10 retryOnFailure: true,
11 maxRetries: 3,
12 onSuccess: (record) => {
13 console.log("Consent recorded:", record.consentId)
14 },
15 },
16 }}
17>

Consent Record Structure

FieldDescription
visitorIdDevice-level unique identifier
consentIdUnique ID for this consent action
categoriesObject with category consent states
actionaccept_all | reject_all | custom | update
timestampISO 8601 when consent was given

GDPR Compliance Checklist

✓ Record timestamp of consent

✓ Record what was consented to (categories)

✓ Record consent version (policy version)

✓ Unique identifier per consent action

✓ Link to device/user for withdrawal requests

✓ Store page URL where consent was given

Database Schema

The migrations are located in the migrations/ directory and are compatible with Supabase CLI.

Running Migrations

terminal
# With Supabase CLI
supabase db push
# Or run directly in SQL editor
# Copy contents of migrations/*.sql

consent_records Table

ColumnTypeDescription
iduuidPrimary key
visitor_idtextDevice-level identifier
consent_iduuidUnique consent action ID
categoriesjsonbConsent categories object
timestamptimestamptzWhen consent was given

File Structure

project structure
cookie-consent-banner/
├── app/ # Next.js app directory
│ ├── (registry)/ # Registry UI page
│ ├── demo/ # Demo page
│ ├── docs/ # Documentation page
│ └── r/ # Registry API routes
├── components/
│ ├── cookie-consent/ # Main component library
│ │ ├── cookie-banner.tsx
│ │ ├── cookie-provider.tsx
│ │ ├── cookie-settings.tsx
│ │ ├── cookie-trigger.tsx
│ │ ├── consent-script.tsx
│ │ ├── use-cookie-consent.ts
│ │ └── types.ts
│ └── ui/ # shadcn/ui components
├── docs/ # Markdown documentation
├── migrations/ # Database migrations
├── public/
│ └── r/ # Generated registry files
└── scripts/ # Build scripts