Home is the plugin that lets you build a real start page for Backstage. It surfaces important info and simple shortcuts in one place. You compose it with cards then let teams personalize the layout with a flexible grid that supports adding, moving, and saving widgets.
It ships with useful pieces you can drop in. Show a search bar, starred entities, featured docs, a quick start card, a company logo, and more. You can also track what people use. The plugin records visits so you can display recently visited pages and top visited pages for quick return paths. These cards help people pick up where they left off.
Typical use cases include a portal launcher with links to tools, a status corner for docs or runbooks, and a personalized dashboard for each engineer. It works well when you want a home page that reflects how your org works without forcing a single layout.
Companies use this pattern today. Spotify says their Backstage homepage is one of the most commonly used pages and helps people quickly find and access things.
Installation Instructions
These instructions apply to self-hosted Backstage only. To use this plugin on Roadie, visit the docs.
Install the package
- From the repo root change into your app package
cd packages/app
- Add the Home plugin
yarn add @backstage/plugin-home
Create the home page component
-
Create the file packages/app/src/components/home/HomePage.tsx
-
Add a simple layout. You can swap in any of the exported components later
// packages/app/src/components/home/HomePage.tsx
import Grid from '@material-ui/core/Grid';
import {
HomePageRandomJoke,
HomePageStarredEntities,
HomePageTopVisited,
HomePageRecentlyVisited,
QuickStartCard,
} from '@backstage/plugin-home';
export const homePage = (
<Grid container spacing={3}>
<Grid item xs={12} md={6}>
<HomePageRandomJoke />
</Grid>
<Grid item xs={12} md={6}>
<HomePageStarredEntities />
</Grid>
<Grid item xs={12} md={6}>
<HomePageTopVisited />
</Grid>
<Grid item xs={12} md={6}>
<HomePageRecentlyVisited />
</Grid>
<Grid item xs={12} md={6}>
<QuickStartCard
title="Onboarding"
modalTitle="Getting started"
docsLinkTitle="Learn more"
docsLink="https://backstage.io/docs/getting-started"
image={<img src="/static/logo.png" alt="quick start" width="100%" height="100%" />}
cardDescription="Helpful links for new users"
/>
</Grid>
</Grid>
);
Add the route
-
Open packages/app/src/App.tsx
-
Import the composition root and your home page element
-
Add the route at the root path
// packages/app/src/App.tsx
import React from 'react';
import { AlertDisplay, OAuthRequestDialog } from '@backstage/core-components';
import { AppRouter } from '@backstage/core-app-api';
import { HomepageCompositionRoot, VisitListener } from '@backstage/plugin-home';
import { homePage } from './components/home/HomePage';
// other imports for your routes
export default app.createRoot(
<>
<AlertDisplay />
<OAuthRequestDialog />
<AppRouter>
<VisitListener />
<Routes>
<Route path="/" element={<HomepageCompositionRoot />}>
{homePage}
</Route>
{/* keep your other routes here */}
</Routes>
</AppRouter>
</>,
);
The HomepageCompositionRoot renders the page shell for the home route. The homePage element you created becomes the page content.
Track page visits
Home offers two cards that need visit data
- HomePageTopVisited
- HomePageRecentlyVisited
Add the VisitListener once in your app root to record visits as users navigate. The snippet above already shows it placed just inside AppRouter.
Provide the visits API
Add a visits API implementation to your app APIs. Pick one of the two options.
-
Open packages/app/src/apis.ts
-
Import the references
-
Register at least one implementation
Using storageApi for persistence linked to the signed in user
// packages/app/src/apis.ts
import {
AnyApiFactory,
createApiFactory,
identityApiRef,
storageApiRef,
errorApiRef,
} from '@backstage/core-plugin-api';
import {
visitsApiRef,
VisitsStorageApi,
} from '@backstage/plugin-home';
// keep your other api factories
export const apis: AnyApiFactory[] = [
// other api factories
createApiFactory({
api: visitsApiRef,
deps: { storageApi: storageApiRef, identityApi: identityApiRef },
factory: ({ storageApi, identityApi }) =>
VisitsStorageApi.create({ storageApi, identityApi }),
}),
];
Or use localStorage in the browser
// packages/app/src/apis.ts
import {
AnyApiFactory,
createApiFactory,
identityApiRef,
errorApiRef,
} from '@backstage/core-plugin-api';
import {
visitsApiRef,
VisitsWebStorageApi,
} from '@backstage/plugin-home';
// keep your other api factories
export const apis: AnyApiFactory[] = [
// other api factories
createApiFactory({
api: visitsApiRef,
deps: { identityApi: identityApiRef, errorApi: errorApiRef },
factory: ({ identityApi, errorApi }) =>
VisitsWebStorageApi.create({ identityApi, errorApi }),
}),
];
Optional customizable home page
You can let users add move configure or remove widgets. Replace your static grid with CustomHomepageGrid. Add the widgets you allow inside the grid.
// packages/app/src/components/home/HomePage.tsx
import {
CustomHomepageGrid,
HomePageRandomJoke,
HomePageStarredEntities,
HomePageTopVisited,
HomePageRecentlyVisited,
} from '@backstage/plugin-home';
export const homePage = (
<CustomHomepageGrid title="Your Dashboard">
<HomePageRandomJoke />
<HomePageStarredEntities />
<HomePageTopVisited />
<HomePageRecentlyVisited />
</CustomHomepageGrid>
);
Optional default layout for the customizable grid
Pass a default config that defines starting positions and sizes.
// packages/app/src/components/home/HomePage.tsx
import {
CustomHomepageGrid,
HomePageStarredEntities,
} from '@backstage/plugin-home';
const defaultConfig = [
{
component: 'HomePageStarredEntities',
x: 0,
y: 0,
width: 6,
height: 4,
movable: true,
resizable: true,
deletable: false,
},
];
export const homePage = (
<CustomHomepageGrid title="Your Dashboard" config={defaultConfig} />
);
You can use the component element instead of a string if you prefer
const defaultConfig = [
{
component: <HomePageStarredEntities />,
x: 0,
y: 0,
width: 6,
height: 4,
},
];
Optional filter for visits in app config
You can filter what the visit cards show. Add this in app-config.yaml
home:
recentVisits:
filterBy:
- field: name
operator: contains
value: service
topVisits:
filterBy:
- field: hits
operator: '>='
value: 2
Run the Backstage config checker if you want to validate the structure
yarn backstage-cli config:check
Backend install notes
This plugin does not ship a backend plugin. You do not need to add anything to the legacy backend system. You do not need to add anything to the new backend system. The visit storage runs in the browser or in the app storage API.
Changelog
This changelog is produced from commits made to the Home plugin since 4 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 i18n support to the home plugin #30140 4 months ago
- Add App Root Elements for VisitListener and SignalsDisplay in the new frontend system #30454 3 months ago
- Add the missing visits API in the new frontend system #30574 2 months ago
Bug fixes
- Fix clear all in CustomHomepageGrid to respect the deletable flag default. Widgets marked as not deletable stay. Others remove by default #30994 2 days ago
- Wait for storage to load before rendering the custom homepage layout. Prevents a brief flicker of default widgets #31085 1 month ago
- Fix clear all so it does not remove widgets marked as not deletable #30788 2 months ago
- Fix WelcomeTitle to default to inherit as before #30171 4 months ago
Breaking changes
- Blueprints with advanced param types now use a define callback form. Update ApiBlueprint usage to params define => define options #30673 2 months ago
- AppRootElementBlueprint now only accepts an element #30703 2 months ago
- Remove the default prefix from blueprint param names. Update any code that used that prefix #30721 2 months ago
- FrontendPlugin no longer exposes override methods. Use OverridableFrontendPlugin if you need overrides #30904 2 months ago
Documentation
- Recommend the name defineParams for blueprint param helpers #30714 2 months ago
Set up Backstage in minutes with Roadie
Focus on using Backstage, rather than building and maintaining it.