Skip to content

Hooks

Define hooks in src/cms/hooks.ts. They run inside the local API on every operation.

import { defineHooks } from "./core/define";
export default defineHooks({
posts: {
beforeCreate(data, context) {
// Auto-generate excerpt from body
if (!data.excerpt && typeof data.body === "object") {
data.excerpt = richTextToPlainText(data.body).slice(0, 180);
}
return data;
},
afterPublish(doc, context) {
context.cache?.invalidate({ tags: ["posts", `post:${doc._id}`] });
},
afterDelete(doc, context) {
context.cache?.invalidate({ tags: ["posts", `post:${doc._id}`] });
},
},
});
HookArgumentsReturn
beforeCreate(data, context)Modified data
afterCreate(doc, context)
beforeUpdate(data, existing, context)Modified data
afterUpdate(doc, context)
beforeDelete(doc, context)
afterDelete(doc, context)
beforePublish(doc, context)
afterPublish(doc, context)
beforeUnpublish(doc, context)
afterUnpublish(doc, context)
beforeSchedule(doc, context)
afterSchedule(doc, context)
{
user: { id, role, email } | null,
operation: "create" | "update" | "delete" | ...,
collection: "posts",
timestamp: "2025-01-01T00:00:00Z",
cache: {
invalidate: ({ tags: string[] }) => void
}
}

Use context.cache.invalidate() in after* hooks to purge Astro’s route cache:

afterPublish(doc, context) {
context.cache?.invalidate({
tags: ["posts", `post:${doc._id}`]
});
},

Tag your Astro pages to match:

---
Astro.cache.set({ tags: ["posts", `post:${post._id}`] });
---