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
+3 -4
View File
@@ -4,7 +4,6 @@ A plugin to help explore the structure of your Backstage app.
This plugin provides the following extensions:
| ID | Type | Description | Default Config |
| ------------------------- | --------- | ------------------------------------ | ------------------------- |
| `page:app-visualizer` | `Page` | The app visualizer page | `{ path: '/visualizer' }` |
| `nav-item:app-visualizer` | `NavItem` | Nav item for the app visualizer page | |
| ID | Type | Description | Default Config |
| --------------------- | ------ | ----------------------- | ------------------------- |
| `page:app-visualizer` | `Page` | The app visualizer page | `{ path: '/visualizer' }` |
-26
View File
@@ -7,7 +7,6 @@ import { AnyRouteRefParams } from '@backstage/frontend-plugin-api';
import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api';
import { ExtensionDataRef } from '@backstage/frontend-plugin-api';
import { ExtensionInput } from '@backstage/frontend-plugin-api';
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';
@@ -19,31 +18,6 @@ const visualizerPlugin: OverridableFrontendPlugin<
{},
{},
{
'nav-item:app-visualizer': 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:app-visualizer': OverridableExtensionDefinition<{
kind: 'page';
name: undefined;
@@ -19,11 +19,15 @@ import {
ExtensionDataRef,
coreExtensionData,
ApiBlueprint,
NavItemBlueprint,
useApi,
routeResolutionApiRef,
appTreeApiRef,
createExtensionDataRef,
} from '@backstage/frontend-plugin-api';
const legacyNavItemTargetDataRef = createExtensionDataRef<unknown>().with({
id: 'core.nav-item.target',
});
import {
Box,
Flex,
@@ -86,7 +90,7 @@ const getOutputColor = createOutputColorGenerator(
[coreExtensionData.routePath.id]: '#ffeb3b',
[coreExtensionData.routeRef.id]: '#9c27b0',
[ApiBlueprint.dataRefs.factory.id]: '#2196f3',
[NavItemBlueprint.dataRefs.target.id]: '#ff9800',
[legacyNavItemTargetDataRef.id]: '#ff9800',
},
['#90caf9', '#ffcc80', '#a5d6a7', '#ef9a9a', '#fff59d', '#ce93d8', '#e6ee9c'],
@@ -335,7 +339,7 @@ const legendMap = {
'Utility API': ApiBlueprint.dataRefs.factory,
'Route Path': coreExtensionData.routePath,
'Route Ref': coreExtensionData.routeRef,
'Nav Target': NavItemBlueprint.dataRefs.target,
'Nav Target': legacyNavItemTargetDataRef,
};
function Legend() {
+1 -10
View File
@@ -17,7 +17,6 @@
import {
createFrontendPlugin,
createRouteRef,
NavItemBlueprint,
PageBlueprint,
PluginHeaderActionBlueprint,
SubPageBlueprint,
@@ -31,6 +30,7 @@ const appVisualizerPage = PageBlueprint.make({
path: '/visualizer',
routeRef: rootRouteRef,
title: 'Visualizer',
icon: <RiEyeLine />,
},
});
@@ -82,14 +82,6 @@ const copyTreeAsJson = PluginHeaderActionBlueprint.make({
},
});
export const appVisualizerNavItem = NavItemBlueprint.make({
params: {
title: 'Visualizer',
icon: () => <RiEyeLine />,
routeRef: rootRouteRef,
},
});
/** @public */
export const visualizerPlugin = createFrontendPlugin({
pluginId: 'app-visualizer',
@@ -101,7 +93,6 @@ export const visualizerPlugin = createFrontendPlugin({
appVisualizerTreePage,
appVisualizerDetailedPage,
appVisualizerTextPage,
appVisualizerNavItem,
copyTreeAsJson,
],
});