Remove NavItemBlueprint in favor of page-based nav discovery

Drop the deprecated NavItemBlueprint from the public API and migrate core
plugins to set title and icon on PageBlueprint instead. AppNav keeps
backward compatibility for legacy nav-item extensions via an internal
core.nav-item.target data ref.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Patrik Oldsberg
2026-05-19 11:00:46 +02:00
parent 6651f2be06
commit 10e5d6f8aa
45 changed files with 165 additions and 905 deletions
-26
View File
@@ -13,7 +13,6 @@ import { ExtensionInput } from '@backstage/frontend-plugin-api';
import { HomePageLayoutProps } from '@backstage/plugin-home-react/alpha';
import { HomePageWidgetBlueprintParams } from '@backstage/plugin-home-react/alpha';
import { HomePageWidgetData } from '@backstage/plugin-home-react/alpha';
import { IconComponent } from '@backstage/frontend-plugin-api';
import { IconElement } from '@backstage/frontend-plugin-api';
import { JSX as JSX_2 } from 'react';
import { OverridableExtensionDefinition } from '@backstage/frontend-plugin-api';
@@ -81,31 +80,6 @@ const _default: OverridableFrontendPlugin<
inputs: {};
params: HomePageWidgetBlueprintParams;
}>;
'nav-item:home': OverridableExtensionDefinition<{
kind: 'nav-item';
name: undefined;
config: {
title: string | undefined;
};
configInput: {
title?: string | undefined;
};
output: ExtensionDataRef<
{
title: string;
icon: IconComponent;
routeRef: RouteRef<undefined>;
},
'core.nav-item.target',
{}
>;
inputs: {};
params: {
title: string;
icon: IconComponent;
routeRef: RouteRef<undefined>;
};
}>;
'page:home': OverridableExtensionDefinition<{
config: {
path: string | undefined;
-5
View File
@@ -38,10 +38,6 @@ describe('Home Plugin Alpha', () => {
it('should export core home page extension', () => {
expect(homePlugin.getExtension('page:home')).toBeDefined();
});
it('should export navigation item extension', () => {
expect(homePlugin.getExtension('nav-item:home')).toBeDefined();
});
});
describe('Optional Extensions (Disabled by Default)', () => {
@@ -99,7 +95,6 @@ describe('Home Plugin Alpha', () => {
it('should include all extensions in the correct order', () => {
// Core extensions (always enabled)
expect(homePlugin.getExtension('page:home')).toBeDefined();
expect(homePlugin.getExtension('nav-item:home')).toBeDefined();
// Optional extensions (disabled by default)
expect(homePlugin.getExtension('api:home/visits')).toBeDefined();
+2 -10
View File
@@ -28,7 +28,6 @@ import { lazy as reactLazy } from 'react';
import {
createExtensionInput,
PageBlueprint,
NavItemBlueprint,
createFrontendPlugin,
createRouteRef,
AppRootElementBlueprint,
@@ -65,6 +64,8 @@ const homePage = PageBlueprint.makeWithOverrides({
path: '/home',
noHeader: true,
routeRef: rootRouteRef,
title: 'Home',
icon: <HomeIcon fontSize="inherit" />,
loader: async () => {
const LazyDefaultLayout = reactLazy(() =>
import('./alpha/DefaultHomePageLayout').then(m => ({
@@ -122,14 +123,6 @@ const visitsApi = ApiBlueprint.make({
}),
});
const homeNavItem = NavItemBlueprint.make({
params: {
title: 'Home',
routeRef: rootRouteRef,
icon: HomeIcon,
},
});
const homePageToolkitWidget = HomePageWidgetBlueprint.make({
name: 'toolkit',
params: {
@@ -213,7 +206,6 @@ export default createFrontendPlugin({
info: { packageJson: () => import('../package.json') },
extensions: [
homePage,
homeNavItem,
visitsApi,
visitListenerAppRootElement,
homePageToolkitWidget,