Reference
Every revalidatePlugin option, default, and export in one place — plus the guarantees the finders and hooks make.
The full surface: plugin options, the import-path map for every export, and the behavioural notes worth knowing. For finder signatures see Writing getters; for the tag vocabulary see The atomic model.
Plugin options
Every option is optional. Zero-config (revalidatePlugin()) gives every collection and global its hooks, and doc tags flow automatically. Declared lists are the one thing worth configuring.
enabledbooleandefault trueMaster switch. Set `false` to register no hooks or endpoints at all.
collectionsRecord<string, CollectionRevalidateConfig | false>default {}
Tracking config for YOUR collections, keyed by slug — this plugin registers none of its own, so there's no `slug`/`overrides` here, just the per-collection settings below. Set a slug to `false` to opt the collection out entirely. Omit it and every collection still gets doc tags — just one bare list tag per collection instead of scoped ones.
idFieldstring | falsedefault 'slug' when a slug field exists, else falseThe field for the alias doc tag (`posts:my-slug`). Defaults to `'slug'` when the collection has a slug field, otherwise the collection is id-keyed only.
listsRecord<string, string[] | { fields: string[] }>Declares list scopes — each scope gives a list surface its own tag and names the fields that reorder or filter it (`name: [fields]`, or the longer `name: { fields: [...] }`).
extraTagsstring[]Fixed tags added to every doc in the collection.
globalsPartial<Record<string, false>>default {}Opt one of YOUR globals out of revalidation by setting its slug to `false`. Every global is tracked by default.
optionsRevalidateOptions
The plugin's own knobs.
prefixstringdefault ''Namespaces every emitted tag (e.g. `prefix: "app:"` → `app:posts:my-slug`). Use it to isolate tags when two Payload apps share a cache.
rulesArray<{ on: string; bust: string[]; whenFields?: string[] }>default []Manual busts for data the field-walk can't see (e.g. content denormalized by an app-level build step). A rule fires when one of its `whenFields` changed, or on any membership event; deletes fire it unconditionally.
observebooleandefault dev onlyForce the dependency-map observation and dev warnings on in production. By default they run in development only. It also governs the `/api/revalidate-map` endpoints: they serve nothing but observations, so when `observe` is off they are not registered at all. With `observe: true` in production they additionally require an authenticated Payload user.
idField is per-collection, not top-level. Set it under collections: { posts: { idField: 'uid' } } (or on the collection's custom.revalidate), not as a revalidatePlugin() option. Likewise walk.maxTags (default 64 — caps how many tags the bake-in walk adds to one entry; Next.js allows 128) is a per-read option you pass to a finder / cacheDoc, not a plugin option. Capped reads are flagged in the dev map.
Finder defaults, baked in so you never repeat them: depth: 0 (references stay
ids), errors resolve to null, and id-list reads
(findIds) are forced to select: {}. Access is not one of them — the finders
leave overrideAccess to Payload's own default (true), so a collection with
restricted read access reads the same through a finder as through payload.find.
Pass overrideAccess: false to scope a read to what an anonymous visitor may see.
Override any default per call — except
user / req, which the finders refuse (see Writing
getters).
Environment variables
None. The plugin reads no environment variables — everything is configured through plugin options.
Endpoints
Two dependency-map routes, governed entirely by observe — dev-only by default. They serve nothing but observations, so with observe: false (the production posture) they are not registered at all. With observe: true forced on in production they additionally require an authenticated Payload user.
| Route | Purpose |
|---|---|
GET /api/revalidate-map | The full dependency map as JSON. |
POST /api/revalidate-map | Bust one tag by hand — body { "tag": "posts:42" }. |
These power the /dev/revalidate map — see Troubleshooting.
CLI commands
The plugin registers one bin, so it runs through Payload's own CLI.
| Command | What |
|---|---|
payload revalidate-map | Renders the static dependency map from your config alone — no running site, no observations, so it's the build-time / CI view of what busts what. Prints a text report by default; --json emits the raw inspection, and --out <file> (-o) writes it to a file instead of stdout. |
Exports
Two import entry points, plus the finders and primitives you get back from the factory.
Package root — @pro-laico/payload-revalidate
| Export | Purpose |
|---|---|
revalidatePlugin | The plugin. Add it last in plugins: []. |
tagsFor | tagsFor(payload) builds prefix-correct raw tags for the rare hand-spelled cacheTag need. |
readRevalidateMarker | readRevalidateMarker(config) returns the typed config.custom.payloadRevalidate — the resolved prefix, observe, lists, extraTags, rules, and the map endpointPath (non-null only while observing). |
getInspection | The live dependency map for this process (observed reads + graph), or null when the plugin isn't active. What GET /api/revalidate-map and /dev/revalidate serve. |
buildStaticInspection · renderRevalidateMap | Build the static map from a config (MapConfigSource) and render it to the text report — the machinery behind payload revalidate-map, for custom CI checks or map UIs. |
Cache helpers — @pro-laico/payload-revalidate/cache
| Export | Purpose |
|---|---|
createCacheHelpers | Seed once with your live Payload handle; returns the finders, primitives, and manual busters below. |
Factory returns — destructured from createCacheHelpers(db), not imported
| Return | Purpose |
|---|---|
findDocByID | One doc by id → its id-keyed entry. The atomic unit. |
findDoc | One doc by query, with alias (as) and draft tagging. |
findIds | An id-list plus pagination meta, no second query. |
findGlobal | A global. |
cacheDoc · cacheIds · cacheGlobal | The low-level primitives a finder wraps, for getters the finders can't express. |
revalidateDoc | Bust one doc's tags. Lane-aware (published + :draft) and prefix-aware. |
revalidateList | Bust a collection's bare list tag plus every declared scope. |
revalidateGlobal | Bust a global's tags. |
revalidateAll | Bust the all tag — every tagged entry. |
Notes
- Add the plugin last in
plugins: []— it can only hook collections that exist when it runs (a boot-time warning names anything registered after it). - Failure paths are loud in every environment, once per process:
cacheTagfailing (entry materializing untagged), the config being unreachable (bake-in walk skipped), andrevalidateTagno-oping outside a request scope allconsole.error/warn— a production jobs runner silently not revalidating is the one thing this plugin refuses to be quiet about. - The map endpoints are registered only while
observeis on, so the production default leaves them off the config entirely. Withobserve: trueforced on in production, they additionally require an authenticated Payload user. - The cache helpers never resolve Payload or your config themselves — no
globalThisstashes, no@payload-configalias tricks, notranspilePackagesrequirement. The handle you seed intocreateCacheHelpersis the session that runs and tags every read. - A draft save over a published doc is indistinguishable from an unpublish in the hook signature, so both lanes bust — a harmless over-bust that keeps unpublish correct.
- Collections without a slug field get no alias tag — id-keyed reads only.
- The bake-in walk is capped (
walk.maxTags, default 64; Next allows 128 tags/entry); capped reads are flagged in the map. - Bare
postslist tags bust on membership only — an unscopedfindIdsread that depends on sort/filter fields should declare a scope instead.
Next
- Writing getters — finder signatures and the
'use cache'pattern. - The atomic model — the tag vocabulary and what busts when.
- Troubleshooting — failure modes and the
/dev/revalidatemap.
Examples
Copy-paste getters for the common caching jobs — detail pages, lists, globals, drafts, sitemaps, manual busts, and migrating off unstable_cache.
Troubleshooting
Fix the common revalidation failures fast — a symptom-first table with the literal dev warnings to grep for, plus the /dev/revalidate map that shows exactly what busts when.