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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@payload-solutions/plugin-consent

v0.1.0

Published

Payload Consent: 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.

Readme

@payload-solutions/plugin-consent

Payload Consent — 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'],
      },
    }),
  ],
})

What it adds

| Slug | Kind | Purpose | | --- | --- | --- | | consent-settings | global | banner copy, jurisdictions, re-consent rules, recording, Consent Mode, versions | | consent-categories | collection | the choices visitors see (necessary, functional, analytics, marketing, …) | | consent-trackers | collection | every script, pixel, embed or cookie, with its category, loader and cookie rows | | consent-records | collection | immutable proof of decisions (no IP), purged after the retention period | | consent-processors | collection (optional) | everyone who receives personal data: recipients, transfers, sub-processors, DPA annex | | legal-pages | collection (optional) | privacy, terms, cookie policy, sub-processors, DPA — with live cookie table and processor table blocks | | GET /api/consent/config | endpoint | everything a client needs, jurisdiction resolved from CDN headers | | POST /api/consent/records | endpoint | records a decision (zod-validated, rate limited) | | GET /api/consent/records/me | endpoint | the logged-in user's consent history | | GET /api/consent/subprocessors | endpoint | the published sub-processor list, its version and change log | | consentPurgeRecords | job task | retention purge | | consent-audits | collection (optional) | stored legal audits, admin-only, with per-finding acceptance and a required reason | | ConsentOverview | admin component | dashboard widget (@payload-solutions/plugin-consent/rsc#ConsentOverview) | | payload-consent | CLI + MCP server | the legal audit: init, scan, mcp, apply, profile |

Legal audit

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:3000 (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.

Not legal advice

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.