WHAT YOU'LL LEARN
  • What are event handlers and when should you use them?
  • How do “Before” and “After” handlers differ?
  • How to implement a real-world event handler using the class-based pattern?
  • How to register event handlers in your project?

Overview
anchor

Event handlers let you hook into Headless CMS lifecycle events — points in time immediately before or after an operation (create, update, delete, publish, etc.) completes. You implement a class, register it as an extension, and the system calls it automatically during that operation.

Use event handlers when you need to:

  • Validate data before it is written (e.g., enforce a unique slug)
  • Trigger side effects after an operation (e.g., notify an external system after an entry is published)
  • Audit or log changes across groups, models, or entries

Event handlers are available for all three Headless CMS resources: Groups, Models, and Entries.

Before vs. After Handlers
anchor

Every operation has two hook points:

Handler typeWhen it runsCan block the operation?Payload contains
BeforeBefore the writeYes — throw an error to abortinput (raw user input), the entity being written
AfterAfter the writeNo — operation already completedThe fully persisted entity

Use Before handlers for validation and authorization. Use After handlers for side effects like sending notifications or syncing data to external systems.

Anatomy of an Event Handler
anchor

Every event handler follows the same structure:

extensions/cms/entry/eventHandler/update/beforeUpdate.ts

Key points:

  • The class must implement the Interface type exported from the abstraction namespace.
  • The handle method receives an event object with payload, occurredAt, and eventType.
  • payload contains the resource-specific data (e.g., entry, model, input).
  • Dependencies are injected via the constructor using the DI system — you do not instantiate them yourself.
  • The file must use export default.

Example: Enforce a Unique Slug
anchor

This Before handler prevents creating an entry when another entry with the same slug value already exists. It queries the database and throws if a duplicate is found.

extensions/cms/entry/eventHandler/create/beforeCreate.ts

Example: Notify an External System on Publish
anchor

This After handler fires after an entry is published. It calls an external webhook with the published entry data.

extensions/cms/entry/eventHandler/publish/afterPublish.ts

Registering Event Handlers
anchor

After creating your handler files, register them in webiny.config.tsx using Api.Extension:

webiny.config.tsx

Each handler file is a separate Api.Extension entry. The order of registration determines the execution order when multiple handlers listen to the same event.

If a Before handler throws an error, the operation is aborted and subsequent handlers for the same event are not called. Design your validation logic accordingly.

Available Events
anchor

Events are organized by resource type. See the reference pages for the full list of available handlers: