Skip to main content
In this guide you’ll build a small frontend plugin for Backstage that fetches a random piece of advice from the Advice API (https://api.adviceslip.com/advice) and renders it as a compact card on an entity page. This practical example demonstrates:
  • How to scaffold a frontend plugin in a Backstage repository
  • How Backstage plugins declare routes and expose extensions
  • How to implement a React component that fetches data using Backstage APIs
  • How to register a component extension so it can be embedded in the app
Prerequisites: a working Backstage repository and basic familiarity with React.
Make sure your development environment can run the Backstage frontend (Node.js, Yarn) and that you understand basic React hooks (useState, useEffect). This example focuses on frontend plugin development and using Backstage APIs like useApi and fetchApiRef.

1) Scaffolding a frontend plugin

Backstage includes a generator to add new packages to a monorepo. From the project root run:
When prompted:
Choose “plugin - A new frontend plugin” and enter an ID such as advice. The generator will create the plugin under plugins/advice and update the root frontend package dependencies (for example, adding "@internal/backstage-plugin-advice": "^0.1.0" to the root package.json). Expected output includes messages like:

2) What the generator creates (important files)

Open plugins/advice/src. The generator provides several files you will use: routes.ts
plugin.ts (routable page example)
The generator also adds tests and a basic Storybook setup for the plugin.

3) Creating a reusable component extension (AdviceCard)

For this lesson we want a small, embeddable component — an AdviceCard — that can be placed on an entity overview page. To make it reusable across the app we will export it as a component extension. Create the component file:
Add a small index file that re-exports the component:
Now expose the component from plugin.ts using createComponentExtension (so other parts of the app can import and render it):
Finally, export the plugin and its extensions from src/index.ts:
Note: The export name you choose (for example AdviceCardExtension) is the identifier other packages will import.

4) Using the plugin in the app

The generator wires the routable AdvicePage into the app router. In packages/app/src/App.tsx you might see:
and a router entry such as:
To embed the Advice card on an entity overview, import the provided component extension into the file that composes the entity “Overview”. For example:
Important: when referencing JSX tags in MDX text, wrap them in backticks to avoid MDX parsing (for example AdviceCardExtension).

5) Styling with Backstage UI components

Backstage uses Material-UI and provides curated UI primitives in @backstage/core-components. Use these building blocks for a consistent look-and-feel rather than custom CSS. Common components: We used InfoCard in the AdviceCard to inherit Backstage styling and accessibility defaults.
A screenshot of a documentation webpage (Material UI) showing the "Card" component with examples and explanatory text. The page includes a left navigation menu of UI components and a right-side contents list.
Backstage also publishes a Storybook with component examples — a helpful resource to discover available components and copy working snippets.
A Storybook UI screenshot showing an "Information Card" component preview with a subheader and lorem ipsum body text. The left sidebar lists components and the lower panel shows controls for the card's props.

6) Why use Backstage APIs for fetch (useApi + fetchApiRef)

Prefer Backstage’s injectable fetch API over the global fetch. Benefits:
  • Centralized configuration (proxying, auth headers, base URLs)
  • Consistent logging and error handling across plugins
  • Easier testability and mocking in unit tests
We used them like this in AdviceCard:
This integrates your requests with the app’s HTTP pipeline and makes it simpler to add auth, retries, or proxy rules later.

7) Running and developing the plugin independently

Develop plugins without booting the entire Backstage app. Common ways:
  • From the plugin folder:
  • From the repo root using Yarn workspaces:
Either command runs a local dev server for the plugin so you can iterate quickly. The server prints the URL, e.g. http://localhost:3000/, where you can preview the plugin UI.
A web app dashboard screenshot with a purple header reading "Welcome to advice!" and a page titled "My Plugin Title" showing an information card and an "Example User List" table of avatars, names, emails, and nationalities. A dark left navigation panel with items like "Root Page," "Switch Theme," and "Sign Out" is also visible.

8) Recap — complete AdviceCard component

For convenience, here is the final AdviceCard.tsx:

That covers creating a simple, reusable frontend plugin in Backstage: scaffolding, registering a component extension, using Backstage UI primitives, and performing API requests through the Backstage fetch API. From here you can extend the plugin with caching, explicit loading/error states, tests, configuration via the Backstage config system, or a backend proxy if you need to avoid CORS or rate limits. Links and references

Watch Video