Browse all documentation

Hooks

Run Go code when content changes. Choose field, collection, or global hooks, and learn when to save related data or notify another service.

Hooks are Go functions that run when Ridu creates, reads, updates, or deletes content. Use them to clean up a field value, record who edited a document, save an audit entry, or send a notification after a successful save.

They run on the server for requests from the admin, REST, the SDK, and the local Go API.

Types of hooks

Hook type Attach it to Use it to
Collection hooks A collection’s Hooks Work with a whole document: record its editor, save an audit entry
Global hooks A global’s Hooks Do the same for a single document, such as site settings
Field hooks A field’s .Hooks(...) and .AfterRead(...) Change one field’s value wherever the field is used
Application hooks Config.Hooks Log failures from every collection and global in one place

A collection hook and a field hook can sit side by side:

go
var Products = ridu.Collection{
  Slug: "products",
  Fields: field.Fields{
    // A field hook changes one value.
    field.Text("sku").Hooks(field.Hooks[string]{
      BeforeChange: []field.Transform[string]{uppercaseSKU},
    }),
    field.Text("lastEditedBy"),
  },
  // A collection hook works with the whole document.
  Hooks: ridu.CollectionHooks{
    BeforeChange: []ridu.Hook{recordLastEditor},
  },
}

A field hook follows the field wherever you reuse it, including inside groups, arrays, and blocks. Use a collection or global hook when several fields need to change together, or when the hook saves other documents. Hook context compares what each kind of hook receives.

Before or after saving?

  • Before saving: clean up or calculate values with BeforeValidate or BeforeChange.
  • After saving, before commit: use AfterChange for related database writes that must succeed or roll back together with the document.
  • After commit: use AfterCommit to notify another service once the document is saved.
  • When preparing a response: use AfterRead to change what the caller receives without changing what is stored. A field registers it with its .AfterRead(...) method, because a field’s returned value can have a different type from its stored value.

Field hooks do not have BeforeRead or AfterError. The field hook arguments and collection hook table show what runs for each operation.

See where validation and field hooks fit for the exact order of a save, including validation, permissions, and field hooks. BeforeOperation and AfterOperation also run for reads; check ctx.Operation when your code should run only on saves.

Ridu waits for each hook to finish. Use tasks for work that needs background processing or retries, and read after-commit behavior before sending email or calling a webhook.

Find an example

Handle errors across the application

Config.Hooks.AfterError runs for failures across the application, including failures that happen before Ridu knows which collection or global is involved. Use it for a central logger or error reporting service:

go
config.Hooks.AfterError = []ridu.Hook{logFailure}

Collection and global AfterError hooks run before the application’s error hooks. See the AfterError example for a logging hook, and Log a failed operation for what happens to a failed write.