betavoidbase is in public beta. It runs, the API is PocketBase's and is not moving, and the version is still 0.x for everything around that.Help us get it to 1.0

vb_hooks

Handlers that run because a record changed, whoever changed it. A route answers a call your own code makes; a hook fires for the SDK, for someone clicking in the admin panel, and for your own routes alike. That is the difference, and it is the reason this directory exists at all.

One hook per file

Any file in vb_hooks/ whose default export is a defineHook is registered once, when the app mounts, in filename order. The first argument is the event, the last are the collections it applies to.

// vb_hooks/slug.ts
import { defineHook } from "@voidbase-cloud/voidbase/adapter";

export default defineHook("onRecordCreateRequest", (e) => {
  e.record.set("slug", String(e.record.get("title")).toLowerCase().replaceAll(" ", "-"));
  e.next();
}, "posts");

It is TypeScript in the project, so it imports what everything else imports: the modules your routes use, the helpers in src/, your own types.

// vb_hooks/notify.ts
import { defineHook } from "@voidbase-cloud/voidbase/adapter";
import { sendDigest } from "@/shared/mail";     // the same module routes/ imports

export default defineHook("onRecordAfterCreateSuccess", async (e) => {
  await sendDigest(e.record.get("author") as string);
  e.next();
}, "posts");

How a handler behaves

e.next() runs the remaining handlers and then the action itself, so work before that call happens first and work after it happens once the write has gone through. Throwing instead refuses the request with that error:

export default defineHook("onRecordUpdateRequest", (e) => {
  if (e.record.get("locked") && !e.auth?.isSuperuser()) throw new ForbiddenError("locked");
  e.next();
}, "posts");

The events are the ones a project's pb_hooks has, with the same names and the same event objects: records as models and as requests, collections, auth, files, realtime, settings, mail and batches. That page lists them, and everything it says about $app, $apis and the rest is true here too.

Three mistakes the build refuses

What you wroteWhat it says
A file in vb_hooks/ that exports no hookThat the file is attached to nothing, rather than silently never running.
An event name that is not one of PocketBase'sThe nearest real ones, because it is almost always a typo.
A defineHook left in middleware/That middleware is Void's and runs per request, and a hook belongs here.

All three are build errors rather than warnings, because each one is a handler that would otherwise never fire and give no sign of it.

Where they end up

The build compiles this directory, along with routes/, middleware/, crons/ and queues/, into the generated instance's single hook bundle. There is nothing to register and no order to maintain beyond the filenames.

Found something wrong on this page?

Fix it yourself. The link below opens this file in GitHub's editor and forks the repository for you if you need one, and your change becomes a pull request without leaving the browser.