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-plugin-cloudflare-purge

v2.4.0

Published

A Payload CMS plugin that automatically purges Cloudflare CDN cache when content changes. This ensures your visitors always see the most recent version of your site without stale cache.

Downloads

43

Readme

Payload Plugin Cloudflare Purge

npm version npm downloads

A Payload CMS plugin that automatically purges Cloudflare CDN cache when content changes. This ensures your visitors always see the most recent version of your site without stale cache.

Features

  • 🚀 Automatic Cache Purge - Purges on content changes for collections and globals.
  • 🔘 UI Button - Optional "Purge Everything" button directly in the Admin Dashboard.
  • Asynchronous Logic - urlBuilder can be async, allowing for complex data fetching to build purge lists.
  • 🌍 Localization Support - Passes the current locale to the URL builder.
  • 🔧 Custom URL Building - Define custom logic for which URLs to purge.
  • 📊 Comprehensive Logging - Detailed logs with correlation IDs for debugging.
  • 🔌 Endpoint Support - Optional internal endpoint for manual purge requests.
  • 🛡️ Typed - Exports all necessary types for a fully typed experience in your project.

Installation

npm install payload-plugin-cloudflare-purge
# or
yarn add payload-plugin-cloudflare-purge
# or
pnpm add payload-plugin-cloudflare-purge

Configuration

Basic Setup

Add the plugin to your payload.config.ts:

import { buildConfig } from 'payload'
import { PayloadPluginCloudflarePurge } from 'payload-plugin-cloudflare-purge'

export default buildConfig({
  plugins: [
    PayloadPluginCloudflarePurge({
      enabled: true,
      zoneId: process.env.CLOUDFLARE_ZONE_ID,
      apiToken: process.env.CLOUDFLARE_API_TOKEN,
      baseUrl: 'https://yourdomain.com',
      collections: ['posts', 'pages'],
      globals: ['header', 'footer'], // Target specific globals (case exist)
      showButtonPurgeEverything: true, // Show the manual purge button in dashboard
    }),
  ], // ... other config
})

Environment Variables

CLOUDFLARE_ZONE_ID=your_zone_id_here
CLOUDFLARE_API_TOKEN=your_api_token_here

Advanced Configuration

PayloadPluginCloudflarePurge({
  enabled: true,
  zoneId: process.env.CLOUDFLARE_ZONE_ID,
  apiToken: process.env.CLOUDFLARE_API_TOKEN,
  baseUrl: 'https://yourdomain.com',
  collections: 'ALL', // Purge for all collections
  events: ['afterChange', 'afterDelete'],
  purgeEverything: false,
  showButtonPurgeEverything: true,
  urlBuilder: ({ doc, collectionSlug }) => {
    // Custom URL building logic
    return [`https://yourdomain.com/${collectionSlug}/${doc.slug}`]
  },
  debug: process.env.NODE_ENV === 'development',
  logCFJSON: false,
  useEndpoint: true,
})

API Endpoint

The plugin adds a POST endpoint at /api/cloudflare-purge for manual purge requests:

// Example manual purge request
const response = await fetch('/api/cloudflare-purge', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: 'Bearer your_token_here', // If not using internal call
  },
  body: JSON.stringify({
    files: ['/specific-url-to-purge'],
    purgeEverything: false,
  }),
})

Options

| Option                       | Type                                   | Default                           | Description                                     | | ---------------------------- | -------------------------------------- | --------------------------------- | ------------------------------------------------ | | enabled                   | boolean                             | false                           | Enable/disable the plugin                       | | zoneId                     | string                               | -                                 | Cloudflare Zone ID                               | | apiToken                   | string                               | -                                 | Cloudflare API Token                             | | baseUrl                   | string                               | -                                 | Your site's base URL                             | | collections               | string[] or 'ALL'                 | []                             | Collections to monitor                           | | globals                   | string[] or 'ALL'                 | []                             | Globals to monitor                               | | localized                 | boolean                             | false                           | Enable localization support (passes locale)   | | events                     | Array<'afterChange'\|'afterDelete'> | ['afterChange', 'afterDelete'] | Events that trigger purge                       | | purgeEverything           | boolean or function               | false                           | Purge entire cache                               | | showButtonPurgeEverything | boolean                             | false                           | Add a "Purge Everything" button to the Dashboard | | urlBuilder                 | function                             | Default builder                   | Custom URL builder function (async supported) | | debug                     | boolean                             | false                           | Enable debug logging                             | | logCFJSON                 | boolean                             | false                           | Log full Cloudflare JSON responses               | | useEndpoint               | boolean                             | true                           | Use internal endpoint for purging               |

Custom URL Builder (Async)

You can provide a custom async function to build URLs, allowing you to fetch additional data needed to create a comprehensive purge list.

import { PayloadPluginCloudflarePurge } from 'payload-plugin-cloudflare-purge'
import type { UrlBuilderArgs } from 'payload-plugin-cloudflare-purge/types'

PayloadPluginCloudflarePurge({
  // ...
  urlBuilder: async (args: UrlBuilderArgs) => {
    const { doc, previousDoc, req, collectionSlug, baseUrl } = args

    if (collectionSlug === 'posts') {
      // Example: Fetch all category pages this post belongs to
      const category = await req.payload.findByID({
        collection: 'categories',
        id: doc.category.id,
      })

      const urls = [`${baseUrl}/posts/${doc.slug}`]
      if (category) {
        urls.push(`${baseUrl}/categories/${category.slug}`)
      }

      // If slug changed, purge the old URL too
      if (previousDoc && previousDoc.slug && previousDoc.slug !== doc.slug) {
        urls.push(`${baseUrl}/posts/${previousDoc.slug}`)
      }

      return urls
    }

    return []
  },
})

Development

The plugin includes a comprehensive development environment:

  1. Start PostgreSQL: docker-compose up -d
  2. Setup environment: Copy .env.example to .env and configure
  3. Install dependencies: pnpm install (or npm/yarn)
  4. Start dev server: pnpm dev
  5. Run tests: pnpm test

Testing

# Run integration tests
pnpm test

# Run tests with watch mode
pnpm test:watch

# Run tests with coverage
pnpm test:coverage

Error Handling

The plugin includes comprehensive error handling:

  • Network failure retries
  • API token validation
  • Zone ID verification
  • Detailed error logging with correlation IDs

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/new-feature
  3. Commit your changes: git commit -am 'Add new feature'
  4. Push to the branch: git push origin feature/new-feature
  5. Submit a pull request

License

MIT License - see LICENSE file for details.

Changelog

v2.4.0 (Latest)

✨ Features

  • Dashboard Purge Button: Added a PurgeEverythingButton component that can be optionally injected into the Admin Dashboard. This allows admins to trigger a "Purge Everything" request directly from the UI.
  • Configurable UI: Introduced the showButtonPurgeEverything option (default: false) to enable the dashboard button.

🐛 Fixes

  • Improved Endpoint Body Parsing: Updated purgeEndpointHandler to correctly handle request bodies in both Next.js Web API environments (using req.json()) and standard Express environments (using req.body). This fixes issues where the manual purge endpoint might fail to read options.

v2.3.0

✨ Features

  • Access to Previous Document: The urlBuilder function now receives a previousDoc argument in the afterChange hook. This allows for comparing the document before and after the change, enabling more advanced cache purging logic, such as purging old URLs when a slug is modified.

🛠️ Improvements

  • Improved Typing: The req object passed to the urlBuilder is now correctly typed as PayloadRequest.

v2.2.0

✨ Features

  • Asynchronous urlBuilder: The urlBuilder function can now be async, allowing for complex logic that needs to fetch data (e.g., querying the Payload API) to build the list of URLs to purge.
  • Exported Types: The plugin now properly exports all its types, allowing for a fully typed implementation in your own project via import type { UrlBuilderArgs } from 'payload-plugin-cloudflare-purge/types'.

v2.1.0

✨ Features

  • Globals Support: The plugin now automatically purges cache for changes in Payload globals. You can configure this with the new globals: ['my-global'] or globals: 'ALL' option.
  • Localization Support: Added a localized: true option. When enabled, the urlBuilder function receives the current locale as a parameter, allowing you to build locale-specific URLs (e.g., /en/my-page).

🛠️ Improvements

  • Logging is now conditional on the debug: true flag to provide a cleaner console output in production.
  • The successful purge log now includes the request body sent to Cloudflare for easier debugging.

v2.0.0

Breaking Changes

  • Switched from default export to named export: use import { PayloadPluginCloudflarePurge } from 'payload-plugin-cloudflare-purge'.
  • Removed unused subpath exports: payload-plugin-cloudflare-purge/client and payload-plugin-cloudflare-purge/rsc.

Migration Guide

  • Update imports in your payload.config.ts and examples:
// Before
// import PayloadPluginCloudflarePurge from 'payload-plugin-cloudflare-purge'

// After
import { PayloadPluginCloudflarePurge } from 'payload-plugin-cloudflare-purge'

v1.0.3

Bug Fixes

  • Fixed circular reference JSON serialization error: Resolved the "Converting circular structure to JSON" error by ensuring hooks return only the document (doc) instead of the complete arguments object (args) which contained circular references between PgTable and PgInteger objects

  • Improved hook compatibility: Modified both afterChangeHook and afterDeleteHook to return the document directly, preventing circular reference issues during Payload CMS response serialization

v1.0.2

  • Draft-aware purge logic - only purges on actual publication
  • Automatic draft configuration detection per collection
  • Improved TypeScript examples in documentation

v1.0.1

  • Fixed export, main and type scripts by package.json
  • Description repository
  • Version package
  • Add badges version and npm

v1.0.0

  • Complete rewrite with TypeScript
  • PostgreSQL support instead of MongoDB
  • Enhanced configuration options
  • Improved error handling and logging
  • Internal endpoint for manual purges
  • Flexible URL building system