Announcements logo

Backstage Announcements Plugin

Created by procore-oss

Announcements is a Backstage plugin that helps teams share important updates inside their developer portal. It gives you a simple place to publish news, changes, and reminders. It also brings those messages to where engineers already work, so they are easy to see and hard to miss.

The plugin includes a full page to browse announcements, a banner that surfaces the latest unseen message, and a card you can drop on a home page. It has an admin portal for creating and managing announcements, categories, and tags. You can schedule start and end dates, filter by category or tag, and mark items active. It integrates with Backstage search so updates show up in global results. It can update in near real time using signals. It can send notifications when a new announcement is created if you enable that in your instance.

Engineers use it to broadcast platform changes, incident and maintenance notes, deprecation plans, and migration guides. It is also useful for policy updates or internal events. The goal is to centralize news, keep context close to code and docs, and reduce the noise of chat and email. If you run a self hosted Backstage, this plugin adds a clear, lightweight way to keep your users informed.

Installation Instructions

These instructions apply to self-hosted Backstage only. To use this plugin on Roadie, visit the docs.

From your Backstage root, install the frontend and backend parts.

Copy
yarn --cwd packages/app add @backstage-community/plugin-announcements
yarn --cwd packages/backend add @backstage-community/plugin-announcements-backend

Expose the announcements page in your app. Add a route in packages/app/src/App.tsx.

Copy
// packages/app/src/App.tsx
import React from 'react';
import { FlatRoutes, Route } from '@backstage/core-app-api';
import { AnnouncementsPage } from '@backstage-community/plugin-announcements';

export const AppRoutes = () => (
  <FlatRoutes>
    <Route path="/announcements" element={<AnnouncementsPage />} />
  </FlatRoutes>
);

Put announcements on your homepage if you want. Here are three options you can drop into your HomePage component.

Copy
// New announcement banner that refreshes in near real time when signals are enabled
import { NewAnnouncementBanner } from '@backstage-community/plugin-announcements';

export const HomePageBanner = () => <NewAnnouncementBanner />;
Copy
// A small card that lists recent items
import { AnnouncementsCard } from '@backstage-community/plugin-announcements';

export const HomePageCard = () => <AnnouncementsCard max={3} />;
Copy
// A timeline view
import { AnnouncementsTimeline } from '@backstage-community/plugin-announcements';

export const HomePageTimeline = () => <AnnouncementsTimeline maxResults={10} />;

Add the search backend module to index announcements into search.

Copy
yarn --cwd packages/backend add @backstage-community/plugin-search-backend-module-announcements

Register the search module in your backend entry point.

Copy
// packages/backend/src/index.ts
import { createBackend } from '@backstage/backend-defaults';

const backend = createBackend();

backend.add(import('@backstage-community/plugin-announcements-backend'));
backend.add(import('@backstage-community/plugin-search-backend-module-announcements'));

backend.start();

Show announcements in the search UI. Add a result type and a list item to your search page.

Copy
// packages/app/src/components/search/SearchPage.tsx
import React from 'react';
import { SearchPage, SearchResult, SearchType } from '@backstage/plugin-search';
import { AnnouncementSearchResultListItem } from '@backstage-community/plugin-announcements';
import RecordVoiceOverIcon from '@mui/icons-material/RecordVoiceOver';

export const MySearchPage = () => (
  <SearchPage>
    <SearchType.Accordion
      name="Result Type"
      defaultValue="software-catalog"
      types={[
        { value: 'announcements', name: 'Announcements', icon: <RecordVoiceOverIcon /> },
      ]}
    />
    <SearchResult>
      <AnnouncementSearchResultListItem />
    </SearchResult>
  </SearchPage>
);

If you use the new frontend system, enable the feature plugin and extensions.

Copy
yarn --cwd packages/app add @backstage-community/plugin-announcements
Copy
// packages/app/src/App.tsx
import announcementsPlugin from '@backstage-community/plugin-announcements/alpha';
import { createApp } from '@backstage/frontend-app-api';

const app = createApp({
  features: [announcementsPlugin],
});

export default app.createRoot();
Copy
# app-config.yaml
app:
  extensions:
    - entity-card:announcements/announcements
    - nav-item:announcements

The entity card appears on component and system entities by default. You can change that with a filter.

Copy
app:
  extensions:
    - entity-card:announcements/announcements:
        config:
          filter: kind:component,system,group,api

Enable the backend on the new backend system. This is the simplest path.

Copy
yarn --cwd packages/backend add @backstage-community/plugin-announcements-backend
Copy
// packages/backend/src/index.ts
import { createBackend } from '@backstage/backend-defaults';

const backend = createBackend();

backend.add(import('@backstage-community/plugin-announcements-backend'));

backend.start();

Add optional real time updates for the banner. This needs events and signals backends.

Copy
yarn --cwd packages/backend add @backstage/plugin-events-backend @backstage/plugin-signals-backend
Copy
// packages/backend/src/index.ts
import { createBackend } from '@backstage/backend-defaults';

const backend = createBackend();

backend.add(import('@backstage/plugin-events-backend'));
backend.add(import('@backstage/plugin-signals-backend'));
backend.add(import('@backstage-community/plugin-announcements-backend'));

backend.start();

Add optional notifications. In the new announcement form you can enable sendNotification. This requires the notifications backend.

Copy
yarn --cwd packages/backend add @backstage/plugin-notifications-backend
Copy
// packages/backend/src/index.ts
const backend = createBackend();

backend.add(import('@backstage/plugin-notifications-backend'));
backend.add(import('@backstage-community/plugin-announcements-backend'));

backend.start();

If you still run the old backend system, wire the legacy router. Create a plugin file and mount it on the API router.

Copy
yarn --cwd packages/backend add @backstage-community/plugin-announcements-backend
Copy
// packages/backend/src/plugins/announcements.ts
import { Router } from 'express';
import { PluginEnvironment } from '../types';
import {
  buildAnnouncementsContext,
  createRouter,
} from '@backstage-community/plugin-announcements-backend';

export default async function createPlugin(env: PluginEnvironment): Promise<Router> {
  const ctx = await buildAnnouncementsContext({
    logger: env.logger,
    database: env.database,
    permissions: env.permissions,
  });

  return await createRouter(ctx);
}
Copy
// packages/backend/src/index.ts
import announcements from './plugins/announcements';

// inside main after createEnv
const announcementsEnv = useHotMemoize(module, () => createEnv('announcements'));
apiRouter.use('/announcements', await announcements(announcementsEnv));

If you need to keep the old system but run the new backend framework shell, you can wrap the legacy router using the helper from backend common. This is a bridge while you migrate.

Copy
// packages/backend/src/index.ts
import { createBackend } from '@backstage/backend-defaults';
import { legacyPlugin } from '@backstage/backend-common';
const backend = createBackend();

backend.add(
  legacyPlugin('announcements', import('./plugins/announcements')),
);

backend.start();

That bridge only helps during migration. Prefer the new backend system long term.

The plugin uses your existing backend database. No extra config is required in app config for a basic setup.

You can customize the page. Here are a few examples you can drop into App.tsx.

Copy
// Change the title length for cards on the page
<AnnouncementsPage cardOptions={{ titleLength: 64 }} />

// Filter to a category
<AnnouncementsPage category="conferences" />

// Pick a markdown renderer
<AnnouncementsPage markdownRenderer="backstage" />

// Hide the start at label on cards
<AnnouncementsPage hideStartAt />

That is it. You now have the page at /announcements, the optional homepage widgets, search integration, and the backend running. If you need notifications or near real time banners, install the extra backend modules shown above.

Changelog

This changelog is produced from commits made to the Announcements plugin since 3 months ago, and based on the code located here. It may not contain information about all commits. Releases and version bumps are intentionally omitted. This changelog is generated by AI.

Features

  • Add search extensions for the new frontend system. Announcements can show in search results. #5490 1 day ago
  • Add defaultActive prop to Router and AnnouncementsPage. You can preselect Active in the new announcement form. #5266 1 day ago
  • Add until date support. Add a current filter to show announcements that are live. Update admin table and create form to include Until. #5245 21 days ago
  • Integrate with Notifications. Announcements can send notifications. #5268 24 days ago
  • Add tag filtering from announcement cards. You can filter by one tag or many. #4623 2 months ago

Improvements

  • Switch the NavItem icon in the new frontend system to RecordVoiceOverIcon to avoid confusion with Notifications. #4838 2 months ago
  • Move optional fields below the editor. Add a border around the Markdown editor. #4637 2 months ago

Bug fixes

  • Fix table styling with the Markdown editor in light theme. #5371 today
  • Send signals or notifications only for active announcements. #5563 today
  • Fix active handling in NewAnnouncementBanner. Send a notification when an announcement is activated on update. Align EditAnnouncementPage navigation with the creation page. #5519 3 days ago
  • Handle null until date values to prevent server errors. #5328 20 days ago
  • Fix editing when an announcement has no category. #5228 27 days ago
  • Fix routing for the new frontend system. Remove the deprecation warning. #4837 2 months ago

Developer experience

  • Add notifications to the dev app for easier testing. #5287 21 days ago

Breaking changes

  • None

Set up Backstage in minutes with Roadie