npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

fredonbytes-consent-cookies

v1.4.8

Published

Next.js consent cookies management with Supabase and optional next-intl support

Readme

FredonBytes Consent Cookies

GDPR-compliant consent management for Next.js with Supabase storage and next-intl internationalization support.

Features

  • 🚀 Easy integration with Next.js 15+ (App Router)
  • Server Component compatible - No performance degradation
  • 🌍 Multilingual support - Built-in: English, Czech, German
  • 🔄 Optional next-intl - Works with or without next-intl
  • 💾 Supabase backend for consent persistence
  • 🎨 Tailwind CSS styling
  • 🔒 GDPR compliant
  • 📦 Lightweight and tree-shakeable
  • 🤖 SEO-friendly - No blocking, robots can crawl

Installation

npm install fredonbytes-consent-cookies
# or
yarn add fredonbytes-consent-cookies
# or
pnpm add fredonbytes-consent-cookies

Quick Start

1. Environment Variables

Add to your .env.local:

NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key

Note: This package requires react, react-dom, and next (>=15.0.0) as peer dependencies. next-intl (>=3.0.0) is optional.

2. Database Setup

Option A: Using Supabase Migrations (Recommended for Production)

This package includes an automated migration file for easy setup.

  1. Copy migration file to your project:
cp node_modules/fredonbytes-consent-cookies/supabase/migrations/* ./supabase/migrations/
  1. Push migrations to your Supabase project:
supabase migration up

Or use the Supabase CLI to apply:

supabase db push

Option B: Manual SQL Setup (Alternative)

If you prefer manual setup, execute the following SQL in your Supabase SQL editor:

-- Enable pgcrypto extension for UUID generation
CREATE EXTENSION IF NOT EXISTS pgcrypto;

-- Cookie Consent Table
CREATE TABLE IF NOT EXISTS consents (
    id BIGSERIAL PRIMARY KEY,
    consent_id UUID UNIQUE NOT NULL,
    
    -- Consent choices (4 categories)
    essential BOOLEAN NOT NULL DEFAULT true,
    analytics BOOLEAN NOT NULL DEFAULT false,
    marketing BOOLEAN NOT NULL DEFAULT false,
    personalization BOOLEAN NOT NULL DEFAULT false,
    
    -- Privacy and tracking
    ip_hash VARCHAR(64), -- SHA-256 hash, only if analytics=true
    user_agent TEXT,
    
    -- Compliance markers
    consent_version VARCHAR(10) NOT NULL DEFAULT '1.0',
    explicit_timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    
    -- Audit trail
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    last_updated TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Indexes
CREATE INDEX IF NOT EXISTS idx_consents_consent_id ON consents(consent_id);
CREATE INDEX IF NOT EXISTS idx_consents_version ON consents(consent_version);
CREATE INDEX IF NOT EXISTS idx_consents_updated ON consents(last_updated);

Graceful Fallback

If Supabase is not configured or unavailable:

  • ✅ Consent banner still displays and can be dismissed
  • ✅ Preferences are stored in browser localStorage
  • ✅ API returns success with warning message
  • ⚠️ No persistent server-side storage until database is configured

This ensures your application gracefully degrades even without database connectivity.

3. Basic Usage (Server-Side Rendering)

Add to your root layout (remains a server component):

import FredonBytesConsent from 'fredonbytes-consent-cookies';

// ✅ This layout stays a server component!
// No "use client" needed - preserves SSR, streaming, and performance
export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <FredonBytesConsent />
        {children}
      </body>
    </html>
  );
}

Why this works:

  • The package now uses automatic JSX runtime (react-jsx)
  • React and jsx-runtime are externalized (not bundled)
  • preserveModules maintains server/client boundaries
  • FredonBytesConsent is a server component wrapper that creates a client boundary only for the consent banner

4. Internationalization (Optional)

Without next-intl (Simple Projects)

The package automatically uses English as fallback. No additional setup needed!

With next-intl (Multi-language Projects)

Merge consent messages with your app translations:

// i18n.ts
import { getRequestConfig } from 'next-intl/server';
import { loadConsentMessages } from 'fredonbytes-consent-cookies/server';

export default getRequestConfig(async ({ requestLocale }) => {
  const locale = await requestLocale;
  
  const appMessages = (await import(`./messages/${locale}.json`)).default;
  const consentMessages = await loadConsentMessages(locale); // Server-side loading

  return {
    locale,
    messages: {
      ...appMessages,
      ...consentMessages, // Adds 'consent.*' keys
    },
  };
});

Supported Languages:

  • en - English (default fallback)
  • cs - Czech
  • de - German

Adding Custom Translations:

If you need a language not supported by the package, add consent.* keys to your project's message files:

// messages/fr.json (example)
{
  "consent": {
    "title": "Préférences des cookies",
    "description": "Nous utilisons des cookies...",
    "acceptAll": "Tout accepter",
    "rejectAll": "Tout rejeter",
    // ... see src/messages/en.json for all keys
  }
}

Advanced Usage

Individual Components

import {
  ConsentBanner,
  ConsentModule,
  ConsentCompact,
  ConsentFooterLinks
} from 'fredonbytes-consent-cookies';

// Use specific components
export function MyLayout() {
  return (
    <>
      <ConsentBanner />
      <ConsentFooterLinks />
    </>
  );
}

// Preference management page
export function PreferencesPage() {
  return <ConsentModule />;
}

Client Utilities

import {
  getConsentPreferences,
  setConsentPreferences,
  hasConsent
} from 'fredonbytes-consent-cookies';

// Check if user has given consent
if (hasConsent()) {
  const prefs = getConsentPreferences();
  if (prefs.analytics) {
    // Initialize analytics
  }
}

TypeScript Support

import type {
  ConsentPreferences,
  ConsentPayload,
  Locale
} from 'fredonbytes-consent-cookies';

const preferences: ConsentPreferences = {
  analytics: true,
  marketing: false,
  preferences: true
};

API Reference

Components

  • FredonBytesConsent (default): Complete consent banner solution
  • ConsentBanner: Modal/banner for first-time consent
  • ConsentModule: Full preferences management UI
  • ConsentCompact: Compact widget version
  • ConsentFooterLinks: Footer links for consent pages

Utilities

  • loadConsentMessages(locale): Load consent translations
  • getConsentLocales(): Get supported locales
  • getConsentPreferences(): Get current preferences
  • setConsentPreferences(prefs): Set preferences
  • hasConsent(): Check if consent exists

Types

  • ConsentPreferences: User consent choices
  • ConsentPayload: Full consent data structure
  • Locale: Supported locale types

Supported Locales

  • cs (Czech) - Default
  • en (English)

Custom locales can be added by providing your own message files.

Environment Variables

| Variable | Required | Description | |----------|----------|-------------| | NEXT_PUBLIC_SUPABASE_URL | Yes | Your Supabase project URL | | NEXT_PUBLIC_SUPABASE_ANON_KEY | Yes | Your Supabase anonymous key |

Performance & Architecture

Server Component First: The default export FredonBytesConsent is a server component wrapper. This means:

  • ✅ Your layout remains a server component
  • ✅ No degradation of SSR, streaming, or suspense
  • ✅ Client boundary created only for the consent widget
  • ✅ Preserves all Next.js performance optimizations

The consent widget itself uses client components internally (for user interactions), but the wrapper ensures your application layout stays server-side rendered.

Peer Dependencies

  • next >= 15.0.0
  • react >= 18.0.0
  • react-dom >= 18.0.0
  • next-intl >= 3.0.0

Development

Build Package

npm run build:package

Local Development

npm run dev

License

MIT ©2025 FredonBytes | Your All-in-one Digital army

Support

For questions or professional services, visit: FredonBytes Site