Merge pull request #33665 from backstage/rugvip/docs-notifications-new-frontend

docs: migrate notifications docs to new frontend system
This commit is contained in:
Patrik Oldsberg
2026-03-30 16:42:19 +02:00
committed by GitHub
4 changed files with 656 additions and 57 deletions
+299
View File
@@ -0,0 +1,299 @@
---
id: index--old
title: Getting Started (Old Frontend System)
description: How to get started with the notifications and signals
---
::::info
This documentation is for Backstage apps that still use the old frontend
system. If your app uses the new frontend system, read the
[current guide](./index.md) instead.
::::
The Backstage Notifications System provides a way for plugins and external services to send notifications to Backstage users.
These notifications are displayed in the dedicated page of the Backstage frontend UI or by frontend plugins per specific scenarios.
Additionally, notifications can be sent to external channels (like email) via "processors" implemented within plugins.
Notifications can be optionally extended with the signals plugin, which provides a push mechanism to ensure users receive notifications immediately.
### Upgrade to the latest version of Backstage
To ensure your version of Backstage has all the latest notifications and signals related functionality, it's important to upgrade to the latest version. The [Backstage upgrade helper](https://backstage.github.io/upgrade-helper/) is a great tool to help ensure that you've made all the necessary changes during the upgrade!
## About notifications
Notifications are messages sent to either individual users or groups.
They are not intended for inter-process communication of any kind.
There are two basic types of notifications:
- **Broadcast**: Messages sent to all users of Backstage.
- **Entity**: Messages delivered to specific listed entities, such as Users or Groups.
Example of use-cases:
- System-wide announcements or alerts
- Notifications for component owners, e.g. build failures, successful deployments, new vulnerabilities
- Notifications for individuals, e.g. updates you have subscribed to, new required training courses
- Notifications pertaining to a particular entity in the catalog: A notification might apply to an entity and the owning team.
## Installation
:::note
As of the `1.42.0` release of Backstage, Notifications and Signals are installed as part of the default `@backstage/create-app` instance which means you won't need to follow the installation steps outlined here. The only exception to this is adding the [Notifications tab to User Settings](#user-specific-notification-settings) to allow managing these settings.
:::
The following sections will walk you through the installation of the various parts of the Backstage Notification System.
### Add Notifications Backend
First we need to add the backend package:
```bash title="From your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-notifications-backend
```
Then we need to add it to our backend:
```ts title="packages/backend/src/index.ts"
const backend = createBackend();
// ...
backend.add(import('@backstage/plugin-notifications-backend'));
```
### Add Notifications Frontend
First we need to add the frontend package:
```bash title="From your Backstage root directory"
yarn --cwd packages/app add @backstage/plugin-notifications
```
To add the notifications main menu, add the following:
```tsx title="packages/app/src/components/Root/Root.tsx"
import { NotificationsSidebarItem } from '@backstage/plugin-notifications';
<SidebarPage>
<Sidebar>
<SidebarGroup>
// ...
<NotificationsSidebarItem />
</SidebarGroup>
</Sidebar>
</SidebarPage>;
```
Also add the route to notifications:
```tsx title="packages/app/src/App.tsx"
import { NotificationsPage } from '@backstage/plugin-notifications';
<FlatRoutes>
// ...
<Route path="/notifications" element={<NotificationsPage />} />
</FlatRoutes>;
```
### Optional: Add Signals
The use of signals is optional but improves the user experience.
#### Optional: Add Signals Backend
Add signals to your backend by first adding the backend package:
```bash title="From your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-signals-backend
```
Then add the signals plugin to your backend:
```ts title="packages/backend/src/index.ts"
const backend = createBackend();
// ...
backend.add(import('@backstage/plugin-signals-backend'));
```
#### Optional: Signals Frontend
Start with adding the frontend package:
```bash title="From your Backstage root directory"
yarn --cwd packages/app add @backstage/plugin-signals
```
To install the plugin, add the `SignalsDisplay` to your app root:
```tsx title="packages/app/src/App.tsx"
import { SignalsDisplay } from '@backstage/plugin-signals';
export default app.createRoot(
<>
<AlertDisplay transientTimeoutMs={2500} />
<OAuthRequestDialog />
{/* highlight-add-next-line */}
<SignalsDisplay />
<AppRouter>
<VisitListener />
<Root>{routes}</Root>
</AppRouter>
</>,
);
```
If the signals plugin is properly configured, it will be automatically discovered by the notifications plugin and used.
### User-specific notification settings
The notifications plugin provides a way for users to manage their notification settings. To enable this, you must
add the `UserNotificationSettingsCard` to your frontend.
```tsx title="packages/app/src/App.tsx"
<Route path="/settings" element={<UserSettingsPage />}>
<SettingsLayout.Route path="/notifications" title="Notifications">
<UserNotificationSettingsCard
originNames={{ 'plugin:scaffolder': 'Scaffolder' }}
/>
</SettingsLayout.Route>
</Route>
```
![Notification Settings](notificationSettings.png)
You can customize the origin names shown in the UI by passing an object where the keys are the origins and the values are the names you want to show in the UI.
Each notification processor will receive its own row in the settings page, where the user can enable or disable notifications from that processor.
### Default notification settings
You can configure default notification settings for all users in your `app-config.yaml` file. This allows you to set up notification preferences globally, such as disabling specific channels or origins by default, implementing an opt-in strategy instead of opt-out.
#### Channel-level defaults
You can set a default enabled state for an entire channel. When set to `false`, the channel uses an opt-in strategy where notifications are disabled by default unless explicitly enabled by the user or for specific origins.
```yaml
notifications:
defaultSettings:
channels:
- id: 'Web'
enabled: false # Opt-in strategy: channel disabled by default
- id: 'Email'
enabled: true # Opt-out strategy: channel enabled by default (default behavior)
```
#### Origin-level defaults
You can also configure defaults for specific origins within a channel:
```yaml
notifications:
defaultSettings:
channels:
- id: 'Web'
enabled: true # Channel is enabled by default
origins:
- id: 'plugin:scaffolder'
enabled: false # Disable scaffolder notifications by default
- id: 'plugin:catalog'
enabled: true # Enable catalog notifications by default
```
#### Topic-level defaults
For even more granular control, you can set defaults for specific topics within origins:
```yaml
notifications:
defaultSettings:
channels:
- id: 'Email'
enabled: false # Email is opt-in by default
origins:
- id: 'plugin:catalog'
enabled: true # But catalog notifications are enabled
topics:
- id: 'entity:validation:error'
enabled: false # Except validation errors
```
**Note:** If a channel's `enabled` flag is not set, it defaults to `true` for backwards compatibility. When a channel is set to `enabled: false`, all origins within that channel default to disabled unless explicitly enabled.
### Automatic notification cleanup
Notifications are deleted automatically after a certain period of time to prevent the database from growing indefinitely
and to keep the user interface clean. The default retention period is set to 1 year, meaning that notifications older
than that will be deleted automatically.
The retention period can be configured by setting the `notifications.retention` in the `app-config.yaml` file.
```yaml
notifications:
retention: 1y
```
If the retention is set to false, notifications will not be automatically deleted.
## Scaffolder Action
:::note
As of the `1.42.0` release of Backstage, the Notifications Scaffolder action is installed as part of the default `@backstage/create-app` instance which means you won't need to follow the installations steps outlined here. Feel free to skip to the [Basic Example](#basic-example).
:::
There is also a Scaffolder action that you can use to send a notification as part of your Software Template.
First we need to add the backend package:
```bash title="From your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-scaffolder-backend-module-notifications
```
Then we need to add it to our backend:
```ts title="packages/backend/src/index.ts"
const backend = createBackend();
// ...
backend.add(
import('@backstage/plugin-scaffolder-backend-module-notifications'),
);
```
### Basic Example
Here's an example of how you can use it in your Software Template, more details and examples can be found in the "Installed actions" screen in your Backstage instances:
```yaml title="template.yaml"
steps:
- id: notify
name: Notify
action: notification:send
input:
recipients: entity
entityRefs:
- user:default/guest
title: 'Template executed'
info: 'Your template has been executed'
severity: 'normal'
```
The example above would send a notification to the Guest user (`user:default/guest`)
## Additional info
An example of a backend plugin sending notifications can be found in the [`@backstage/plugin-scaffolder-backend-module-notifications` package](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-notifications).
Sources of the notifications and signals plugins:
- [notifications](https://github.com/backstage/backstage/blob/master/plugins/notifications)
- [notifications-backend](https://github.com/backstage/backstage/blob/master/plugins/notifications-backend)
- [notifications-common](https://github.com/backstage/backstage/blob/master/plugins/notifications-common)
- [notifications-node](https://github.com/backstage/backstage/blob/master/plugins/notifications-node)
- [signals-backend](https://github.com/backstage/backstage/blob/master/plugins/signals-backend)
- [signals](https://github.com/backstage/backstage/blob/master/plugins/signals)
- [signals-node](https://github.com/backstage/backstage/blob/master/plugins/signals-node)
- [signals-react](https://github.com/backstage/backstage/blob/master/plugins/signals-react)
+64 -54
View File
@@ -4,6 +4,13 @@ title: Getting Started
description: How to get started with the notifications and signals
---
::::info
This documentation is written for the new frontend system, which is the default
in new Backstage apps. If your Backstage app still uses the old frontend system,
read the [old frontend system version of this guide](./index--old.md)
instead.
::::
The Backstage Notifications System provides a way for plugins and external services to send notifications to Backstage users.
These notifications are displayed in the dedicated page of the Backstage frontend UI or by frontend plugins per specific scenarios.
Additionally, notifications can be sent to external channels (like email) via "processors" implemented within plugins.
@@ -12,7 +19,7 @@ Notifications can be optionally extended with the signals plugin, which provides
### Upgrade to the latest version of Backstage
To ensure your version of Backstage has all the latest notifications and signals related functionality, its important to upgrade to the latest version. The [Backstage upgrade helper](https://backstage.github.io/upgrade-helper/) is a great tool to help ensure that youve made all the necessary changes during the upgrade!
To ensure your version of Backstage has all the latest notifications and signals related functionality, it's important to upgrade to the latest version. The [Backstage upgrade helper](https://backstage.github.io/upgrade-helper/) is a great tool to help ensure that you've made all the necessary changes during the upgrade!
## About notifications
@@ -35,7 +42,7 @@ Example of use-cases:
:::note
As of the `1.42.0` release of Backstage, Notifications and Signals are installed as part of the default `@backstage/create-app` instance which means you won't need to follow the installations steps outlined here. The only exception to this is adding the [Notifications tab to User Settings](#user-specific-notification-settings) to allow managing these settings.
As of the `1.42.0` release of Backstage, Notifications and Signals are installed as part of the default `@backstage/create-app` instance which means you won't need to follow the installation steps outlined here. The only exception to this is adding the [Notifications sidebar item](#add-notifications-sidebar-item) and optionally [Notifications tab to User Settings](#user-specific-notification-settings).
:::
@@ -65,35 +72,29 @@ First we need to add the frontend package:
yarn --cwd packages/app add @backstage/plugin-notifications
```
To add the notifications main menu, add the following:
Once installed, the notifications plugin is automatically available in your app through the default feature discovery. It provides a notifications page at `/notifications` and the notifications API. For more details and alternative installation methods, see [installing plugins](../frontend-system/building-apps/05-installing-plugins.md).
```tsx title="packages/app/src/components/Root/Root.tsx"
### Add Notifications Sidebar Item
The notifications plugin does not yet include a built-in navigation item, so you need to add the `NotificationsSidebarItem` component to your sidebar manually. If you have a custom sidebar through a `NavContentBlueprint`, add the component there:
```tsx
import { NotificationsSidebarItem } from '@backstage/plugin-notifications';
<SidebarPage>
<Sidebar>
<SidebarGroup>
// ...
<NotificationsSidebarItem />
</SidebarGroup>
</Sidebar>
</SidebarPage>;
```
Also add the route to notifications:
```tsx title="packages/app/src/App.tsx"
import { NotificationsPage } from '@backstage/plugin-notifications';
<FlatRoutes>
// ...
<Route path="/notifications" element={<NotificationsPage />} />
</FlatRoutes>;
// Inside your NavContentBlueprint component:
<Sidebar>
<SidebarGroup label="Menu" icon={<MenuIcon />}>
{/* ... other items ... */}
</SidebarGroup>
<SidebarGroup label="Settings" icon={<SettingsIcon />} to="/settings">
<NotificationsSidebarItem />
</SidebarGroup>
</Sidebar>;
```
### Optional: Add Signals
The use of signals is optional but improves the user experience.
The use of signals is optional but improves the user experience by providing real-time push updates.
#### Optional: Add Signals Backend
@@ -119,42 +120,51 @@ Start with adding the frontend package:
yarn --cwd packages/app add @backstage/plugin-signals
```
To install the plugin, add the `SignalsDisplay` to your app root:
```tsx title="packages/app/src/App.tsx"
import { SignalsDisplay } from '@backstage/plugin-signals';
export default app.createRoot(
<>
<AlertDisplay transientTimeoutMs={2500} />
<OAuthRequestDialog />
{/* highlight-add-next-line */}
<SignalsDisplay />
<AppRouter>
<VisitListener />
<Root>{routes}</Root>
</AppRouter>
</>,
);
```
If the signals plugin is properly configured, it will be automatically discovered by the notifications plugin and used.
Once installed, the signals plugin is automatically available in your app through the default feature discovery. No additional configuration is required. If the signals plugin is properly configured, it will be automatically discovered by the notifications plugin and used.
### User-specific notification settings
The notifications plugin provides a way for users to manage their notification settings. To enable this, you must
add the `UserNotificationSettingsCard` to your frontend.
The notifications plugin provides a way for users to manage their notification settings. To enable this, you can create a frontend module that adds a settings tab to the user-settings plugin using the `SubPageBlueprint`:
```tsx title="packages/app/src/App.tsx"
<Route path="/settings" element={<UserSettingsPage />}>
<SettingsLayout.Route path="/notifications" title="Notifications">
<UserNotificationSettingsCard
originNames={{ 'plugin:scaffolder': 'Scaffolder' }}
/>
</SettingsLayout.Route>
</Route>
```tsx title="packages/app/src/modules/NotificationSettingsPage.tsx"
import { Content } from '@backstage/core-components';
import { UserNotificationSettingsCard } from '@backstage/plugin-notifications';
export function NotificationSettingsPage() {
return (
<Content>
<UserNotificationSettingsCard
originNames={{ 'plugin:scaffolder': 'Scaffolder' }}
/>
</Content>
);
}
```
```tsx title="packages/app/src/modules/notificationSettings.tsx"
import { createFrontendModule } from '@backstage/frontend-plugin-api';
import { SubPageBlueprint } from '@backstage/frontend-plugin-api';
export const notificationSettingsModule = createFrontendModule({
pluginId: 'user-settings',
extensions: [
SubPageBlueprint.make({
name: 'notifications',
params: {
path: 'notifications',
title: 'Notifications',
loader: () =>
import('./NotificationSettingsPage').then(m => (
<m.NotificationSettingsPage />
)),
},
}),
],
});
```
Then install the module in your app by adding it to the features array of `createApp`, or through default feature discovery if your app is set up for it.
![Notification Settings](notificationSettings.png)
You can customize the origin names shown in the UI by passing an object where the keys are the origins and the values are the names you want to show in the UI.
+283
View File
@@ -0,0 +1,283 @@
---
id: usage--old
title: Usage (Old Frontend System)
description: How to use the notifications and signals
---
::::info
This documentation is for Backstage apps that still use the old frontend
system. If your app uses the new frontend system, read the
[current guide](./usage.md) instead.
::::
## Notifications Backend
The notifications backend plugin provides an API to create notifications, list notifications per logged-in user, and search based on parameters.
The plugin uses a relational [database](https://backstage.io/docs/getting-started/config/database) for persistence; no specifics are introduced in this context.
No additional configuration in the app-config is needed, except for optional additional modules for `processors`.
## Notifications Frontend
The recipients of notifications have to be entities in the catalog, e.g., of the User or Group kind.
Otherwise, no specific configuration is needed for the front-end notifications plugin.
All parametrization is done through component properties, such as the `NotificationsSidebarItem`, which can be used as an active left-side menu item in the front-end.
![Notifications Page](notificationsPage.png)
In the `packages/app/src/components/Root/Root.tsx`, tweak the [properties](https://backstage.io/api/stable/functions/_backstage_plugin-notifications.index.NotificationsSidebarItem.html) of the `<NotificationsSidebarItem />` per specific needs.
## Usage
New notifications can be sent either by a backend plugin or by an external service through the REST API.
## Backend
Regardless of technical feasibility, a backend plugin should avoid directly accessing the notifications REST API.
Instead, it should integrate with the `@backstage/plugin-notifications-node` to `send` (create) a new notification.
The reasons for this approach include the propagation of authorization in the API request and improved maintenance and backward compatibility in the future.
```ts
import { notificationService } from '@backstage/plugin-notifications-node';
export const myPlugin = createBackendPlugin({
pluginId: 'myPlugin',
register(env) {
env.registerInit({
deps: {
// ...
notificationService: notificationService,
},
async init({
// ...
notificationService,
}) {
httpRouter.use(
await createRouter({
// ...
notificationService,
}),
);
},
});
},
});
```
To emit a new notification:
```ts
await notificationService.send({
recipients /* of the broadcast or entity type */,
payload /* actual message */,
});
```
Consult the [API documentation](https://github.com/backstage/backstage/blob/master/plugins/notifications-node/report.api.md) for further details.
### External Services
When the emitter of a notification is a Backstage backend plugin, it is mandatory to use the integration via `@backstage/plugin-notifications-node` as described above.
If the emitter is a service external to Backstage, an HTTP POST request can be issued directly to the API, assuming that authentication is properly configured.
Refer to the [service-to-service auth documentation](https://backstage.io/docs/auth/service-to-service-auth) for more details, focusing on the Static Tokens section for the simplest setup option.
An example request for creating a broadcast notification might look like:
```bash
curl -X POST https://[BACKSTAGE_BACKEND]/api/notifications -H "Content-Type: application/json" -H "Authorization: Bearer YOUR_BASE64_SHARED_KEY_TOKEN" -d '{"recipients":{"type":"broadcast"},"payload": {"title": "Title of broadcast message","link": "http://foo.com/bar","severity": "high","topic": "The topic"}}'
```
### Scaffolder Templates
You can use the `@backstage/plugin-scaffolder-backend-module-notifications` to send notifications when scaffolder templates are run. To install the module, add it to your backend plugin:
```bash
yarn workspace backend add @backstage/plugin-scaffolder-backend-module-notifications
```
Then, add the module to your backend:
```ts
const backend = createBackend();
// ...
backend.add(
import('@backstage/plugin-scaffolder-backend-module-notifications'),
);
```
In your template you can now use `notification:send` action as part of the steps:
```yaml
steps:
- id: notify
name: Notify
action: notification:send
input:
recipients: entity
entityRefs:
- component:default/backstage
title: 'Template executed'
info: 'Your template has been executed'
severity: 'info'
link: https://backstage.io
```
## Signals
The use of signals with notifications is optional but generally enhances user experience and performance.
When a notification is created, a new signal is emitted to a general-purpose message bus to announce it to subscribed listeners.
The frontend maintains a persistent connection (WebSocket) to receive these announcements from the notifications channel.
The specific details of the updated or created notification should be retrieved via a request to the notifications API, except for new notifications, where the payload is included in the signal for performance reasons.
In a frontend plugin, to subscribe to notifications' signals:
```ts
import { useSignal } from '@backstage/plugin-signals-react';
const { lastSignal } = useSignal<NotificationSignal>('notifications');
React.useEffect(() => {
/* ... */
}, [lastSignal, notificationsApi]);
```
#### Using signals in your own plugin
It's possible to use signals in your own plugin to deliver data from the backend to the frontend in near real-time.
To use signals in your own frontend plugin, you need to add the `useSignal` hook from `@backstage/plugin-signals-react` from `@backstage/plugin-notifications-common` with optional generic type of the signal.
```ts
// To use the same type of signal in the backend, this should be placed in a shared common package
export type MySignalType = {
user: string;
data: string;
// ....
};
const { lastSignal } = useSignal<MySignalType>('my-plugin');
useEffect(() => {
if (lastSignal) {
// Do something with the signal
}
}, [lastSignal]);
```
To send signals from the backend plugin, you must add the `signalsServiceRef` to your plugin or module as a dependency.
```ts
import { signalsServiceRef } from '@backstage/plugin-signals-node';
export const myPlugin = createBackendPlugin({
pluginId: 'my',
register(env) {
env.registerInit({
deps: {
httpRouter: coreServices.httpRouter,
signals: signalsServiceRef,
},
async init({ httpRouter, signals }) {
httpRouter.use(
await createRouter({
signals,
}),
);
},
});
},
});
```
To send the signal using the service, you can use the `publish` method.
```ts
signals.publish<MySignalType>({ user: 'user', data: 'test' });
```
## Consuming Notifications
In a front-end plugin, the simplest way to query a notification is by its ID:
```ts
import { useApi } from '@backstage/core-plugin-api';
import { notificationsApiRef } from '@backstage/plugin-notifications';
const notificationsApi = useApi(notificationsApiRef);
notificationsApi.getNotification(yourId);
// or with connection to signals:
notificationsApi.getNotification(lastSignal.notification_id);
```
## Metadata Field
The metadata field is a freeform object that is designed to be used by processors.
### Well-known Notification Metadata Fields
Below are metadata fields that will be commonly used between processors and have defined schematics.
#### backstage.io/body.markdown
```ts
# Example:
const payload = {
title: 'Entities Require Attention',
description: 'Entities: Service A, Service B',
metadata: {
'backstage.io/body.markdown': `
# Entities
- Service A
- System B
`
}
}
```
This value of this metadata field should be the notification message in markdown format. This allows additional formatting options for processors that support markdown.
### Usage
Below is an example of using the `backstage.io/body.markdown` metadata field in a custom processor.
When sending a notification:
```ts
notificationService.send({
recipients: { type: 'entity', entityRef: 'group/default:team-a' },
payload: {
title: 'Notification',
description: 'Description'
metadata: {
'backstage.io/body.markdown': `
### Notification
Description
`,
},
},
});
```
In the processor, you can then use the metadata field accordingly:
```ts
async postProcess(notification: Notification): Promise<void> {
// We suggest you parse the metadata field with a schema, i.e. Zod
const parseResult = CustomProcessorMetadataSchema.safeParse(notification.payload.metadata ?? {});
const metadata = parseResult.success ? parseResult.data : {};
customNotificationSender.send({
to: getUsers(notification.recipients),
subject: notification.payload.title,
markdownText: metadata['backstage.io/body.markdown'] ?? notification.payload.description,
});
}
```
+10 -3
View File
@@ -4,6 +4,13 @@ title: Usage
description: How to use the notifications and signals
---
::::info
This documentation is written for the new frontend system, which is the default
in new Backstage apps. If your Backstage app still uses the old frontend system,
read the [old frontend system version of this guide](./usage--old.md)
instead.
::::
## Notifications Backend
The notifications backend plugin provides an API to create notifications, list notifications per logged-in user, and search based on parameters.
@@ -18,11 +25,11 @@ The recipients of notifications have to be entities in the catalog, e.g., of the
Otherwise, no specific configuration is needed for the front-end notifications plugin.
All parametrization is done through component properties, such as the `NotificationsSidebarItem`, which can be used as an active left-side menu item in the front-end.
The `NotificationsSidebarItem` component can be used as an active left-side menu item in the front-end. Since the notifications plugin does not yet include a built-in navigation item, it needs to be added manually to your sidebar through a `NavContentBlueprint` in a custom app module. See the [Getting Started](./index.md#add-notifications-sidebar-item) guide for setup instructions.
![Notifications Page](notificationsPage.png)
In the `packages/app/src/components/Root/Root.tsx`, tweak the [properties](https://backstage.io/api/stable/functions/_backstage_plugin-notifications.index.NotificationsSidebarItem.html) of the `<NotificationsSidebarItem />` per specific needs.
You can customize the sidebar item using its [properties](https://backstage.io/api/stable/functions/_backstage_plugin-notifications.index.NotificationsSidebarItem.html) to fit your specific needs.
## Usage
@@ -225,7 +232,7 @@ Below are metadata fields that will be commonly used between processors and have
# Example:
const payload = {
title: 'Entities Require Attention',
description: 'Entities: Service A, Service B'
description: 'Entities: Service A, Service B',
metadata: {
'backstage.io/body.markdown': `
# Entities