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
-53
View File
@@ -10,7 +10,6 @@ import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api';
import { ExtensionBlueprintParams } 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';
@@ -44,31 +43,6 @@ const _default: OverridableFrontendPlugin<
params: ApiFactory<TApi, TImpl, TDeps>,
) => ExtensionBlueprintParams<AnyApiFactory>;
}>;
'nav-item:search': 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:search': OverridableExtensionDefinition<{
config: {
noTrack: boolean;
@@ -214,33 +188,6 @@ export const searchApi: OverridableExtensionDefinition<{
) => ExtensionBlueprintParams<AnyApiFactory>;
}>;
// @alpha (undocumented)
export const searchNavItem: 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>;
};
}>;
// @alpha (undocumented)
export const searchPage: OverridableExtensionDefinition<{
config: {
+3 -11
View File
@@ -37,7 +37,6 @@ import {
ApiBlueprint,
createExtensionInput,
PageBlueprint,
NavItemBlueprint,
configApiRef,
} from '@backstage/frontend-plugin-api';
@@ -110,6 +109,8 @@ export const searchPage = PageBlueprint.makeWithOverrides({
return originalFactory({
path: '/search',
routeRef: rootRouteRef,
title: 'Search',
icon: <SearchIcon fontSize="inherit" />,
loader: async () => {
const getResultItemComponent = (result: SearchResult) => {
const value = inputs.items.find(item =>
@@ -258,22 +259,13 @@ export const searchPage = PageBlueprint.makeWithOverrides({
},
});
/** @alpha */
export const searchNavItem = NavItemBlueprint.make({
params: {
routeRef: rootRouteRef,
title: 'Search',
icon: SearchIcon,
},
});
/** @alpha */
export default createFrontendPlugin({
pluginId: 'search',
title: 'Search',
icon: <SearchIcon fontSize="inherit" />,
info: { packageJson: () => import('../package.json') },
extensions: [searchApi, searchPage, searchNavItem],
extensions: [searchApi, searchPage],
routes: {
root: rootRouteRef,
},