plugin consent logo

plugin consent

by mpresecan
payload-solutions

Cookie consent managed in the Payload admin: categories, trackers, banner, script gating and consent records.

Other
v3
>=3.79.0 <4
MIT

Overview

Summary generated from the README

Adds collections and globals for consent settings, categories, trackers, immutable consent records, processors and legal pages. A single config endpoint drives the frontend banner, script gating and the generated cookie table. Includes a CLI and MCP server for legal audits. Requires Payload 3.79 or newer; React and Next.js helpers come in companion packages.

Features

  • Consent categories and trackers managed as collections with cookie rows and loaders
  • Config endpoint resolves jurisdiction from CDN headers for banner and script gating
  • Immutable consent records without IP, purged after a retention period by a job task
  • Legal pages with live cookie table and processor table blocks
  • Optional processor register and sub-processor list endpoint with change log
  • CLI scan and MCP server audit documents against your configuration

Use cases

  • Add a GDPR or CCPA cookie banner whose scripts only load after visitor consent
  • Publish privacy policy and cookie policy pages with auto-generated cookie tables
  • Keep auditable proof of visitor consent decisions with automatic retention purge

From the author

Cookie Consent for Payload: cookie categories, trackers, legal pages and consent records managed in the Payload admin; one endpoint drives the banner, script gating and the generated cookie table.

Installation

npm i @payload-solutions/plugin-consent

2

Stars

0

Forks

0

Open Issues

Today

Last Updated

2

Weekly Downloads

v0.1.1

npm Version

1.0 MB

Unpacked Size

2

Dependencies

Repository stars

Trends appear after 7 days of data. Daily snapshots have not started yet.

Shared by 5 plugins in mpresecan/payload-solutions.

npm weekly downloads

Trends appear after 7 days of data. Daily snapshots have not started yet.

Each point is npm's rolling 7-day download count.

Health Score

64/100Good

Composite score based on GitHub activity, stars, npm downloads, publish recency, dependency count, and package size.

Badge for your README

Payload Directory health badge
Markdown
[![Payload Directory](https://payloaddirectory.dev/badge/1356812914-plugin-consent.svg)](https://payloaddirectory.dev/plugins/1356812914-plugin-consent)
HTML
<a href="https://payloaddirectory.dev/plugins/1356812914-plugin-consent"><img src="https://payloaddirectory.dev/badge/1356812914-plugin-consent.svg" alt="Payload Directory"></a>
Updated Oct 26, 2026Created Sep 4, 2026Published Oct 24, 2026

README

Cookie Consent for Payload — admin screenshot

Cookie Consent for Payload — cookie categories, trackers, legal pages and consent records managed in the Payload admin. One config endpoint drives the banner, the script gating and the generated cookie table, so they can never disagree.

Documentation: https://payload.solutions/docs/plugins/payload-consent

pnpm add @payload-solutions/plugin-consent @payload-solutions/consent-react
// payload.config.ts
import { consentPlugin } from '@payload-solutions/plugin-consent'

export default buildConfig({
  plugins: [
    consentPlugin({
      seed: {
        company: { name: 'Acme', legalName: 'Acme Ltd', address: '1 Main St, Dublin', email: '[email protected]', url: 'https://acme.com' },
        trackers: ['posthog-eu', 'stripe'],
        processors: ['vercel', 'neon', 'resend', 'stripe', 'posthog-eu', 'sentry'],
      },
    }),
  ],
})

Screenshots

Cookies & scripts

Cookies & scripts — the list that drives the banner, script gating and the cookie table.

The consent banner

The banner from the registry: Reject all next to Accept all.

The processor register

The processor register behind the privacy policy and the DPA annex.

Consent records

Immutable consent records.

More in the documentation: https://payload.solutions/docs/plugins/payload-consent

What it adds

SlugKindPurpose
consent-settingsglobalbanner copy, jurisdictions, re-consent rules, recording, Consent Mode, versions
consent-categoriescollectionthe choices visitors see (necessary, functional, analytics, marketing, …)
consent-trackerscollectionevery script, pixel, embed or cookie, with its category, loader and cookie rows
consent-recordscollectionimmutable proof of decisions (no IP), purged after the retention period
consent-processorscollection (optional)everyone who receives personal data: recipients, transfers, sub-processors, DPA annex
legal-pagescollection (optional)privacy, terms, cookie policy, sub-processors, DPA — with live cookie table and processor table blocks
GET /api/consent/configendpointeverything a client needs, jurisdiction resolved from CDN headers
POST /api/consent/recordsendpointrecords a decision (zod-validated, rate limited)
GET /api/consent/records/meendpointthe logged-in user's consent history
GET /api/consent/subprocessorsendpointthe published sub-processor list, its version and change log
consentPurgeRecordsjob taskretention purge
consent-auditscollection (optional)stored legal audits, admin-only, with per-finding acceptance and a required reason
ConsentOverviewadmin componentdashboard widget (@payload-solutions/plugin-consent/rsc#ConsentOverview)
payload-consentCLI + MCP serverthe legal audit: init, scan, mcp, apply, profile
npx payload-consent init    # MCP server entry, the legal skill, AGENTS.md
npx payload-consent scan    # deterministic checks: no model, no network, no API key

scan compares your documents against your own configuration and proves what it finds: template tokens printed literally, processor rows nobody verified, a locale with no translation, a vendor in package.json that appears in no recipients table, personal data in your Payload schema that the register does not account for. It needs a database but not published pages, so the best time to run it is before launch.

mcp starts a stdio MCP server your own agent drives — Claude Code, Cursor, Codex, whatever you already use. The package contains no model code and no AI SDK: model-agnostic here is the absence of a wrapper, not a wrapper over four providers. The agent reads pages as markdown (with {{cookie-table}}-style tokens for generated tables), walks a checklist with citations, and must quote the text behind every judgement it reports.

Legal facts — the controller's identity, the legal basis per purpose, retention periods — are never invented. The agent asks you in the terminal and records the answer on the compliance profile; consent_propose refuses any draft that depends on an unanswered question. Drafts land as draft versions of the page and are never published.

Full documentation: https://payload.solutions/docs/plugins/payload-consent/audit

Frontend

React / Next.js: @payload-solutions/consent-react. Any other frontend: fetch /api/consent/config and use @payload-solutions/consent-core.

// app/layout.tsx (Next.js App Router)
import { cookies, headers } from 'next/headers'
import { getConsentConfig } from '@payload-solutions/plugin-consent/server'
import { ConsentModeScript, ConsentProvider } from '@payload-solutions/consent-react'
import { ConsentBanner } from '@/components/consent/consent-banner' // npx shadcn@latest add https://payload.solutions/r/consent-banner.json

const payload = await getPayload({ config })
const consent = await getConsentConfig(payload, { headers: await headers() })
const cookie = (await cookies()).get(consent.cookie.name)?.value

<ConsentProvider config={consent} initialCookie={cookie}>
  <ConsentModeScript config={consent} cookie={cookie} />
  {children}
  <ConsentBanner />
</ConsentProvider>

Legal pages render with the plugin's converters, which add the cookie-table and policy-version and processor-table blocks and replace Lexical's inline-styled tables with semantic, unstyled ones (<thead>/<tbody>, scoped <th>, a scroll wrapper):

import { RichText } from '@payloadcms/richtext-lexical/react'
import { legalPageConverters } from '@payload-solutions/plugin-consent/rsc'

<RichText
  converters={({ defaultConverters }) => ({ ...defaultConverters, ...legalPageConverters(data) })}
  data={page.content}
/>

Server code reads the same cookie the browser wrote:

import { readConsent } from '@payload-solutions/consent-react/next'
const consent = readConsent(await cookies(), config)
if (consent.has('analytics')) { /* … */ }

Development

This package follows the Payload plugin template: src/ is the plugin, dev/ is a full Next.js + Payload app that uses it.

cp dev/.env.example dev/.env       # SQLite file, no external services
pnpm dev                           # http://localhost:3320 (frontend demo) and /admin ([email protected] / test)
pnpm test:int                      # vitest against a real Payload instance (throwaway SQLite)
PAYLOAD_CONFIG_PATH=$PWD/dev/payload.config.ts node bin.js scan   # the CLI against the dev app
pnpm test:e2e                      # Playwright: admin login, banner flow, cookie table (run `pnpm exec playwright install chromium` once)
pnpm build                         # tsc declarations + swc to dist/
pnpm generate:types                # after changing collections
pnpm generate:importmap            # after adding admin components

The dev app seeds four categories, PostHog / GA4 / Stripe / YouTube trackers, seven processors and five legal pages on first boot. Send an x-vercel-ip-country header (or ?consent_jurisdiction=US on the config endpoint) to try other jurisdictions; without a header the opt-in fallback applies. pnpm dev runs webpack because Turbopack does not resolve the template's .js → .tsx import convention across the workspace; pnpm dev:turbo is there if that changes.

This plugin helps you publish and enforce your privacy choices. It does not provide legal advice; have the seeded documents reviewed for your jurisdiction. Seeded Terms follow the Common Paper Cloud Service Agreement model (CC BY 4.0); the cookie policy structure is adapted from General Legal (CC0).

MIT © Payload Solutions. Payload, the Payload design, and related marks, designs, and logos are trademarks or registered trademarks of Payload CMS, Inc. in the U.S. and other countries. This project is independent and not affiliated with Payload CMS, Inc.

Similar plugins