Skip to content

Hooks

Define hooks directly in your collection config. They run inside the local API on every operation.

src/cms/collections/posts.ts
import { defineCollection, fields, richTextToPlainText } from "@kidecms/core";
export default defineCollection({
slug: "posts",
labels: { singular: "Post", plural: "Posts" },
fields: {
title: fields.text({ required: true }),
body: fields.richText(),
excerpt: fields.text({ maxLength: 300 }),
},
hooks: {
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}`] });
},
},
});
Hook Arguments Return
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) —
beforeUpsertTranslation (data, locale, existing, context) Modified data

before* hooks on create/update receive the data and can modify it before saving. All other before* hooks can throw to abort the operation. after* hooks are for side effects like cache invalidation.

beforeUpsertTranslation is the only hook that fires on upsertTranslation — beforeCreate and beforeUpdate do not fire there.

{
user: { id, role, email } | null,
operation: "create" | "update" | "delete" | ...,
collection: "posts",
timestamp: "2025-01-01T00:00:00Z",
cache: {
invalidate: ({ tags: string[] }) => void
}
}

Call context.cache.invalidate() in after* hooks to refresh cached pages. Apart from deleteMany(), which clears the collection tag, nothing is invalidated automatically. The tagging and invalidation pattern is in Caching.