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
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 -
urlBuildercan beasync, allowing for complex data fetching to build purge lists. - 🌍 Localization Support - Passes the current
localeto 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-purgeConfiguration
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_hereAdvanced 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:
- Start PostgreSQL:
docker-compose up -d - Setup environment: Copy
.env.exampleto.envand configure - Install dependencies:
pnpm install(or npm/yarn) - Start dev server:
pnpm dev - Run tests:
pnpm test
Testing
# Run integration tests
pnpm test
# Run tests with watch mode
pnpm test:watch
# Run tests with coverage
pnpm test:coverageError Handling
The plugin includes comprehensive error handling:
- Network failure retries
- API token validation
- Zone ID verification
- Detailed error logging with correlation IDs
Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature/new-feature - Commit your changes:
git commit -am 'Add new feature' - Push to the branch:
git push origin feature/new-feature - Submit a pull request
License
MIT License - see LICENSE file for details.
Changelog
v2.4.0 (Latest)
✨ Features
- Dashboard Purge Button: Added a
PurgeEverythingButtoncomponent 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
showButtonPurgeEverythingoption (default:false) to enable the dashboard button.
🐛 Fixes
- Improved Endpoint Body Parsing: Updated
purgeEndpointHandlerto correctly handle request bodies in both Next.js Web API environments (usingreq.json()) and standard Express environments (usingreq.body). This fixes issues where the manual purge endpoint might fail to read options.
v2.3.0
✨ Features
- Access to Previous Document: The
urlBuilderfunction now receives apreviousDocargument in theafterChangehook. 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
reqobject passed to theurlBuilderis now correctly typed asPayloadRequest.
v2.2.0
✨ Features
- Asynchronous
urlBuilder: TheurlBuilderfunction can now beasync, 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 newglobals: ['my-global']orglobals: 'ALL'option. - Localization Support: Added a
localized: trueoption. When enabled, theurlBuilderfunction receives the currentlocaleas a parameter, allowing you to build locale-specific URLs (e.g.,/en/my-page).
🛠️ Improvements
- Logging is now conditional on the
debug: trueflag 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/clientandpayload-plugin-cloudflare-purge/rsc.
Migration Guide
- Update imports in your
payload.config.tsand 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
