Skip to main content

umbraco-notifications

Run server-side C# when something happens in Umbraco 17+ (content saved, published, unpublished, moved, deleted, media or members changed, the application started), or raise your own notification for other code to observe. Use this whenever the user asks to "run code when a page is published", "hook into publish/save/delete", "block or cancel a publish", "subscribe to a notification", write an INotificationHandler, "do something on startup", or "publish a custom notification/event" from a service or background job. SKIP: non-Umbraco projects, Umbraco < 17, backoffice toast notifications (UMB_NOTIFICATION_CONTEXT, a backoffice-extension concern), the editor "Notifications" email subscriptions, and plain POST-to-URL on standard events, which built-in Webhooks already cover.

Source facts

Repository
umbraco/Umbraco-CMS-Implementation-Skills
Last source activity
October 21, 2026 at 08:26
Detected SKILL.md language
English
Stars
7
Forks
8

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
18 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
umbraco-notifications
description
Run server-side C# when something happens in Umbraco 17+ (content saved, published, unpublished, moved, deleted, media or members changed, the application started), or raise your own notification for other code to observe. Use this whenever the user asks to "run code when a page is published", "hook into publish/save/delete", "block or cancel a publish", "subscribe to a notification", write an INotificationHandler, "do something on startup", or "publish a custom notification/event" from a service or background job. SKIP: non-Umbraco projects, Umbraco < 17, backoffice toast notifications (UMB_NOTIFICATION_CONTEXT, a backoffice-extension concern), the editor "Notifications" email subscriptions, and plain POST-to-URL on standard events, which built-in Webhooks already cover.
# Notification handlers Umbraco publishes a notification for most things it does, usually as a before/after pair (`ContentPublishingNotification` / `ContentPublishedNotification`). You react with a registered handler class, and you can publish notifications of your own. **Check first:** if the user only wants an HTTP call to a URL on publish/unpublish/delete (or media save/delete), built-in [Webhooks](https://docs.umbraco.com/umbraco-cms/develop-with-umbraco/headless-and-apis/webhooks.md) (Settings > Webhooks) do that with no code. Point them there and stop. | | **A: Handle a built-in notification** (default) | **B: Publish your own notification** | |---|---|---| | Reference | [approach-a-handle-builtin.md](references/approach-a-handle-builtin.md) | [approach-b-publish-custom.md](references/approach-b-publish-custom.md) | | You write | A handler (`INotificationHandler<T>` or async variant) + one registration line | A notification class, the publish call, usually a handler | | Shipped code | `assets/PublishingRuleHandler.cs`, `assets/NotificationHandlersComposer.cs` | `assets/ContentImportCompletedNotification.cs`, `assets/ContentImportCompletedHandler.cs` | | Best for | Reacting to or vetoing what Umbraco does | Letting other code react to what your service/job does | **Before writing any code, open the reference for the approach you choose and start from its assets.** The facts the docs pages leave out (cache-refresher payloads, cancelled publishes, scope delivery) are only there. ### How to decide "When Umbraco does X, do Y" is A, which is nearly everything. Pick B when the event is your own code and others should be able to listen without referencing it. A job that publishes its own notification plus a handler for it uses both. ## Version compatibility **Umbraco 17+.** API details in the references were checked against Umbraco 17.5; the shipped code is gated on the 17 reference instance. ## Best practices - **Right half of the pair.** Veto or alter in the "before" notification (`CancelOperation`); do side effects in the "after" one. "After" notifications can't be cancelled (they have no `CancelOperation`), and "before" side effects run even if the operation fails. - **Handlers are created fresh per notification.** Fields don't survive between calls; keep state in an injected service. Pass data before-to-after via the notification's `State`. - **"Published" ran here; "cache refreshed" runs everywhere.** `ContentPublishedNotification` fires once, on the server that published. `ContentCacheRefresherNotification` fires on every server after its own cache has updated, so use it for per-server work (local caches) and for anything that must see the published state on other nodes of a load-balanced site. - **Languages change what fires.** Unpublishing one language is a publish of the rest, so it arrives as `ContentPublishingNotification`. Use `IsPublishingCulture` / `IsUnpublishingCulture`. - **Keep startup handlers quick** (they run every boot; see `umbraco-common-pitfalls`), and gate them on `IRuntimeState.Level == RuntimeLevel.Run`: they also fire during install and upgrade boots. `umbraco-composing` covers startup work and runtime levels in full. - **Register the way the project already does:** existing `IComposer`s, or the `CreateUmbracoBuilder()` chain in `Program.cs`. If neither, a composer. ## Validation Assertions live in [`evals/evals.json`](evals/evals.json); run them with `umbraco-skill-evaluator`.
View on GitHub