payload-smart-cache
v1.2.4
Published
Payload Plugin for Cached Data
Maintainers
Readme
payload-smart-cache
Intelligent, dependency-aware cache invalidation for Next.js + Payload CMS applications.
Overview
payload-smart-cache hooks into Payload's save and publish flow to provide automatic, dependency-aware cache invalidation. It builds a dependency graph from your collection and global relationships and walks it on every change, revalidating all affected Next.js cache tags — including indirectly related collections and globals.
Features
- Dependency graph — automatically discovers relationships between collections, so changing a referenced document revalidates its dependents.
- Tag-based revalidation — precise, granular cache invalidation via Next.js
revalidateTag(). - Versions-aware — for versioned collections, cache invalidation only fires on publish, not on draft saves.
- Request caching utility —
createRequestHandlerwraps data-fetching functions with collection/global-level cache tags for automatic revalidation.
Installation
pnpm add payload-smart-cacheUsage
Important: smartCachePlugin scans collection and global fields at config time to auto-discover referenced collections. It must be listed after any plugin that registers collections or injects relationship fields, so those are visible during the scan.
// payload.config.ts
import { buildConfig } from "payload";
import { discussionsPlugin } from "payload-discussions";
import { smartCachePlugin } from "payload-smart-cache";
export default buildConfig({
// ...
plugins: [
discussionsPlugin({ collections: ["posts"] }), // registers collections & injects fields
smartCachePlugin({
collections: ["pages", "posts"],
globals: ["site-settings"],
}), // must come after
],
});Wrap your data-fetching functions with createRequestHandler so they are cached by collection/global tags and automatically revalidated when those collections or globals change:
import { createRequestHandler } from "payload-smart-cache";
const getPosts = createRequestHandler(
async () => {
const payload = await getPayload({ config });
return payload.find({ collection: "posts" });
},
["posts"], // collection/global slugs — revalidated when posts change
);You can pass additional cache options as a third argument:
const getPosts = createRequestHandler(
async () => {
const payload = await getPayload({ config });
return payload.find({ collection: "posts" });
},
["posts"],
{ revalidate: 60 }, // also revalidate every 60 seconds
);| Cache Option | Type | Default | Description |
| ------------- | ------------------ | ------- | -------------------------------------------------------------------- |
| tags | string[] | [] | Additional cache tags beyond the collection/global slugs. |
| revalidate | number \| false | false | Time-based revalidation in seconds, or false for tag-based only. |
Options
| Option | Type | Default | Description |
| --------------------- | ----------------------------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------- |
| collections | CollectionSlug[] | [] | Collections to track changes for. Referenced collections are auto-tracked. |
| globals | GlobalSlug[] | [] | Globals to track changes for. Referenced collections are auto-tracked. |
| disableAutoTracking | boolean | false | Disable automatic tracking of collections referenced via relationship/upload fields. |
| onInvalidate | (change) => void \| Promise<void> | — | Called when cache invalidation fires for a registered collection ({ type: 'collection', slug, docID }) or global ({ type: 'global', slug }). |
Contributing
This plugin lives in the payload-plugins monorepo.
Development
pnpm install
# watch this plugin for changes
pnpm --filter payload-smart-cache dev
# run the Payload dev app (in a second terminal)
pnpm --filter sandbox devThe sandbox/ directory is a Next.js + Payload app that imports plugins via workspace:* — use it to test changes locally.
Code quality
- Formatting & linting — handled by Biome, enforced on commit via husky + lint-staged.
- Commits — must follow Conventional Commits with a valid scope (e.g.
fix(payload-smart-cache): ...). - Changesets — please include a changeset in your PR by running
pnpm release.
Issues & PRs
Bug reports and feature requests are welcome — open an issue.
License
MIT
