Badges adds tiny status images for your Backstage catalog. They show facts like owner, lifecycle, docs, and component name. You place them outside Backstage. For example in a repository readme or a docs site. Each badge links back to the right entity page so people can jump into the catalog fast.
The plugin adds a Badges item to the entity page menu. Open it to see all badges for that entity. Copy the markdown it gives you. Paste it where you want the badge to show. The images are rendered from catalog data, so they stay current as your metadata changes.
Common uses are simple. Mark the owner on every repo. Show lifecycle on the main readme. Prove docs exist on a service page. Give a quick path back to your portal from external docs. Signal standards or maturity across teams without extra work.
You can choose which badges exist in your setup. The backend decides the set of badges and how they look. There is support for obfuscation when badges are public. That helps reduce the risk of people guessing entity names while still keeping badges visible.
If you run Backstage yourself, Badges helps spread clear signals across your codebase. It turns catalog facts into small links people actually see and use.
Installation Instructions
These instructions apply to self-hosted Backstage only.
Install the frontend package
- From your Backstage root run
yarn --cwd packages/app add @backstage-community/plugin-badges
Register the frontend plugin
-
If you already use a plugins file add the import there
// packages/app/src/plugins.ts import { badgesPlugin } from '@backstage-community/plugin-badges';
Then make sure your App uses that plugins file
// packages/app/src/App.tsx + import * as plugins from './plugins'; const app = createApp({ apis, + plugins: Object.values(plugins), bindRoutes({ bind }) { /* ... */ }, });
-
If you do not use a plugins file you can register the plugin in App directly
// packages/app/src/App.tsx + import { badgesPlugin } from '@backstage-community/plugin-badges'; const app = createApp({ apis, + plugins: [badgesPlugin], bindRoutes({ bind }) { /* ... */ }, });
Add the badges menu to your entity page
-
Open your entity page component
packages/app/src/components/catalog/EntityPage.tsx
-
Add the imports
import { EntityBadgesDialog } from '@backstage-community/plugin-badges'; import BadgeIcon from '@material-ui/icons/CallToAction';
-
Update the React import to include the needed hooks
- import React from 'react'; + import React, { ReactNode, useMemo, useState } from 'react';
-
Add the layout wrapper right after the imports
const EntityLayoutWrapper = (props: { children?: ReactNode }) => { const [badgesDialogOpen, setBadgesDialogOpen] = useState(false); const extraMenuItems = useMemo(() => { return [ { title: 'Badges', Icon: BadgeIcon, onClick: () => setBadgesDialogOpen(true), }, ]; }, []); return ( <> <EntityLayout UNSTABLE_extraContextMenuItems={extraMenuItems}> {props.children} </EntityLayout> <EntityBadgesDialog open={badgesDialogOpen} onClose={() => setBadgesDialogOpen(false)} /> </> ); };
-
Wrap your entity routes with the wrapper
const defaultEntityPage = ( + <EntityLayoutWrapper> <EntityLayout.Route path="/" title="Overview"> {overviewContent} </EntityLayout.Route> <EntityLayout.Route path="/docs" title="Docs"> <EntityTechdocsContent /> </EntityLayout.Route> <EntityLayout.Route path="/todos" title="TODOs"> <EntityTodoContent /> </EntityLayout.Route> + </EntityLayoutWrapper> );
Optional badge URL obfuscation in the frontend
-
Add the setting in app config
# app-config.yaml app: badges: obfuscate: true
-
Expose the config to the frontend
// packages/app/src/config.d.ts export interface Config { app: { badges: { /** * badges obfuscate * @visibility frontend */ obfuscate?: string; }; }; }
-
Make sure your app package includes the schema
// packages/app/package.json { "files": [ "dist", "config.d.ts" ], "configSchema": "config.d.ts" }
-
The backend must be configured to support obfuscation Match your backend config with this setting
Install the backend plugin new backend system
-
Add the backend package
yarn --cwd packages/backend add @backstage-community/plugin-badges-backend
-
Register the plugin in your backend entry point
// packages/backend/src/index.ts import { createBackend } from '@backstage/backend-defaults'; import { badgesPlugin } from '@backstage-community/plugin-badges-backend'; const backend = createBackend(); backend.add(badgesPlugin()); backend.start();
-
The service exposes routes under the badges path Your app will serve them under api badges
-
If you use obfuscation add the related backend config as required by the plugin
Install the backend plugin legacy backend system
-
Add the backend package
yarn --cwd packages/backend add @backstage-community/plugin-badges-backend
-
Create the plugin router
// packages/backend/src/plugins/badges.ts import { Router } from 'express'; import { createRouter } from '@backstage-community/plugin-badges-backend'; import type { PluginEnvironment } from '../types'; import { CatalogClient } from '@backstage/catalog-client'; export default async function createPlugin(env: PluginEnvironment): Promise<Router> { const catalogClient = new CatalogClient({ discoveryApi: env.discovery }); return await createRouter({ logger: env.logger, config: env.config, catalogClient, }); }
-
Mount the router in the backend
// packages/backend/src/index.ts import Router from 'express-promise-router'; import { ServerTokenManager } from '@backstage/backend-common'; import type { PluginEnvironment } from './types'; import catalog from './plugins/catalog'; + import badges from './plugins/badges'; async function main() { const logger = getRootLogger(); const config = await loadBackendConfig(); const tokenManager = ServerTokenManager.noop(); const env: PluginEnvironment = await createEnv({ logger, config, tokenManager }); const apiRouter = Router(); apiRouter.use('/catalog', await catalog(env)); + apiRouter.use('/badges', await badges(env)); const service = createServiceBuilder(module) .setPort(7007) .addRouter('/api', apiRouter); await service.start(); }
-
Your app will serve the badges under api badges
-
If you use obfuscation add the related backend config as required by the plugin
Where to see the plugin in the UI
- Open any entity page in your Backstage app
- Use the three dots menu on the top right
- Click Badges to open the dialog
- Copy the markdown for the badges you want and put it in your repository readme or docs
Changelog
This changelog is produced from commits made to the Badges plugin since a year 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
- Support style and color query params in obfuscated mode. Badge style selection now works when obfuscation is on #5139 merged 1 month ago
Deprecations
- Deprecate the legacy badges backend. Migrate to the new backend API soon #2044 merged 10 months ago
Documentation
- Update README links to point to the community plugins repo #3931 merged 5 months ago
Maintenance
Set up Backstage in minutes with Roadie
Focus on using Backstage, rather than building and maintaining it.