Cookie Management
A React/Zustand module for cookie consent, for conditional rendering components based on user consent, with context for global state management. This is a collection of React Components and Typescript Functions that together serve a specific purpose.
Preview
This is how the code looks like in action.
Heads up!
We use cookies to enhance the functionality of this website in order to give you the best experience. Cool?
Learn more in ourPrivacy Policy and ourCookie Policy
Step-By-Step Guide
1. Install Dependencies
State management by Zustand
cli
1npm install zustand
Icons by Lucide. But you can use any or none.
cli
1npm install lucide-react
Button component by shadcn/ui
cli
1npx shadcn-ui@latest add button
Copy the function 'cn'. Link -> cn Function
2. Copy the Source Code
- The persistent store
@/state/useCookieConsentStore.ts
1// Purpose: Store for managing the cookie consent
2
3// Import Types
4// Import External Packages
5import { create } from 'zustand';
6import { createJSONStorage, persist } from 'zustand/middleware';
7// Import Components
8// Import Functions & Actions & Hooks & State
9// Import Data
10// Import Assets & Icons
11
12interface CookieConsentState {
13 hasCookieConsent: boolean | null;
14 setCookieConsent: (hasConsent: boolean | null) => void;
15}
16
17export const useCookieConsentStore = create(
18 persist<CookieConsentState>(
19 (set) => ({
20 hasCookieConsent: null,
21 setCookieConsent: (hasCookieConsent: boolean | null) =>
22 set({ hasCookieConsent }),
23 }),
24 {
25 name: 'cookie-consent',
26 storage: createJSONStorage(() => localStorage),
27 }
28 )
29);
- The hook
@/state/useCookieConsent.ts
1// Purpose: Custom hook to manage cookie consent
2
3// Import Types
4// Import External Packages
5// Import Components
6// Import Functions & Actions & Hooks & State
7import { useCookieConsentStore } from '@/state/useCookieConsentStore';
8// Import Data
9// Import Assets & Icons
10
11export function useCookieConsent() {
12 const { hasCookieConsent, setCookieConsent } = useCookieConsentStore();
13
14 const acceptCookies = () => setCookieConsent(true);
15 const denyCookies = () => setCookieConsent(false);
16
17 return {
18 hasCookieConsent,
19 acceptCookies,
20 denyCookies,
21 };
22}
- The Banner
@/components/CookieConsentBanner.tsx
1'use client';
2
3// Import Types
4// Import External Packages
5import { useState, useEffect } from 'react';
6import Link from 'next/link';
7// Import Components
8import { Button, ButtonProps } from '@/ui/Button';
9// Import Functions & Actions & Hooks & State
10import { useCookieConsent } from '@/state/useCookieConsent';
11import { cn } from '@/lib/utils';
12// Import Data
13// Import Assets & Icons
14import { CookieIcon } from 'lucide-react';
15
16export function CookieConsentButton_Accept({
17 buttonText = 'Accept',
18 variant = 'default',
19 className,
20}: {
21 buttonText?: string;
22 variant?: ButtonProps['variant'];
23 className?: string;
24}) {
25 const { acceptCookies } = useCookieConsent();
26
27 return (
28 <Button
29 variant={variant}
30 onClick={acceptCookies}
31 className={cn(className)}
32 >
33 {buttonText}
34 </Button>
35 );
36}
37
38export function CookieConsentButton_Deny({
39 buttonText = 'Deny',
40 variant = 'secondary',
41 className,
42}: {
43 buttonText?: string;
44 variant?: ButtonProps['variant'];
45 className?: string;
46}) {
47 const { denyCookies } = useCookieConsent();
48
49 return (
50 <Button
51 variant={variant}
52 onClick={denyCookies}
53 className={cn(className)}
54 >
55 {buttonText}
56 </Button>
57 );
58}
59
60/**
61 * Renders a cookie consent banner component.
62 * The banner is displayed to users who have not yet given their consent to use cookies, and only appears after first scroll.
63 */
64export default function CookieConsentBanner() {
65 const { hasCookieConsent } = useCookieConsent();
66 const [showOnScroll, setShowOnScroll] = useState(false);
67
68 // Note: This prevents the banner from flickering when a user that previously provided consent returns to the website.
69 useEffect(() => {
70 const handleFirstScroll = () => {
71 setShowOnScroll(true);
72 window.removeEventListener('scroll', handleFirstScroll);
73 };
74
75 if (hasCookieConsent === null) {
76 window.addEventListener('scroll', handleFirstScroll);
77 }
78
79 return () => {
80 window.removeEventListener('scroll', handleFirstScroll);
81 };
82 }, [hasCookieConsent]);
83
84 if (hasCookieConsent !== null || !showOnScroll) return null;
85
86 return (
87 <div className="fixed left-6 bottom-6 shadow-lg shadow-neutral-500 z-50 max-w-96 bg-white dark:bg-dark-gray dark:text-white p-4 rounded-md">
88 <h2 className="text-lg font-semibold inline-flex leading-6 py-2">
89 Heads up! <CookieIcon className="mx-2" />
90 </h2>
91 <p className="text-muted-foreground">
92 We use cookies to enhance the functionality of this website in order to
93 give you the best experience. Cool?
94 </p>
95 <p className="py-2 text-muted-foreground">
96 Learn more in our
97 <Link
98 href="/privacy-policy"
99 className="underline whitespace-nowrap px-2"
100 >
101 Privacy Policy
102 </Link>{' '}
103 and our
104 <Link
105 href="/cookie-policy"
106 className="underline whitespace-nowrap px-2"
107 >
108 Cookie Policy
109 </Link>
110 </p>
111 <div className="grid justify-items-end">
112 <div className="space-x-2">
113 <CookieConsentButton_Deny />
114 <CookieConsentButton_Accept />
115 </div>
116 </div>
117 </div>
118 );
119}
3. Use in your App
- Add Banner to global layout
layout.tsx
1import CookieConsentBanner from '@/components/CookieConsentBanner';
2
3export default async function RootLayout({
4 children,
5}: Readonly<{
6 children: React.ReactNode;
7}>) {
8 return (
9 {/* The rest of your HTML components */}
10 <body>
11 <CookieConsentBanner />
12 {/* The rest of your app components */}
13 </body>
14 {/* The rest of your HTML components */}
15 );
16}
- Make components dependent on user consent
@/components/SomeComponent.tsx
1import { useCookieConsent } from '@/state/useCookieConsent';
2
3const CookieDependentComponent = () => {
4 const { hasConsent } = useCookieConsent();
5
6 if (!hasConsent) return null;
7
8 return <div>Cookie-dependent content here</div>;
9};
Tech Stack
Only the finest ingredients are used in our products. We made sure that we only use the best technologies available which offer a free tier! Yes, you read that right. Everything can be set up for FREE!
Example Usage
See this component live in action. Are you using the component on your website? Shoot us an email (support@boilerplatehq.com) and we will link to you.
BoilerplateHQ
We use this as our cookie banner and management component!
Your Website?
Are you using this component? Shoot us an email and we will link to you.
You May Also Like
Didn't find what you were looking for? Check out these other items.
Ui Component Library
Want to create your own Ui Component Library like shadcn/ui? This is your template!
Button BackToTop
Renders a button component that scrolls the page to the top when clicked.
Breadcrumps
Renders a breadcrumb component that displays the current page's path.
Frequently Asked Questions
We have compiled a list of frequently asked questions. If you have any other questions, please do not hesitate to contact us via email or using the chat function. We are here to help!