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
-92
View File
@@ -32,7 +32,6 @@ To link that a component provides or consumes an API, see the [`providesApis`](h
- [Packages](#packages)
- [Routes](#routes)
- [Extensions](#extensions)
- [Apis Nav Item](#apis-nav-item)
- [Apis Explorer Page](#apis-explore-page)
- [Apis Entity Cards](#apis-entities-cards)
- [Has Apis Entity Card](#has-apis-entity-card)
@@ -135,94 +134,6 @@ Route binding is also possible through code. For more information, see [this](ht
### Extensions
#### Apis Nav Item
This [nav item](https://backstage.io/docs/reference/frontend-plugin-api.createnavitemextension) extension adds a link to the Apis Explorer page in the main app sidebar.
| Kind | Namespace | Name | Id |
| ---------- | ---------- | ---- | ------------------- |
| `nav-item` | `api-docs` | - | `nav-item:api-docs` |
##### Disable
This extension is enabled by default when you install the `api-docs` plugin, but you can disable it and prevent it from showing up in the sidebar by setting the following configuration:
```yaml
# app-config.yaml
app:
extensions:
# this is the extension id and it follows the naming pattern bellow:
# <extension-kind>/<plugin-namespace>:<extension-name>
# example disabling the apis docs nav item extension
- nav-item:api-docs: false
# or
# - nav-item:api-docs:
# disabled: true
```
To enable the extension again, simple remove the previous `nav-item:api-docs: false` configuration or do:
```yaml
# app-config.yaml
app:
extensions:
# this is the extension id and it follows the naming pattern bellow:
# <extension-kind>/<plugin-namespace>:<extension-name>
- nav-item:api-docs
# or
# - nav-item:api-docs: true
# or
# - nav-item:api-docs:
# disabled: false
```
##### Config
The apis nav item can be customized under the `app.extensions.nav-item:api-docs.config` key in `app-config.yaml`. Configurations include:
```yaml
# app-config.yaml
# example configuring the apis docs nav item extension
app:
extensions:
# this is the extension id and it follows the naming pattern bellow:
# <extension-kind>/<plugin-namespace>:<extension-name>
- nav-item:api-docs:
config:
# The nav item title text, defaults to "APIs"
title: 'Apis Explorer'
# The nav item path text, defaults to "/api-docs"
path: '/apis-explorer'
```
##### Override
The apis nav item icon can only be changed by overriding the extension, as the icon cannot be changed via the `app-config.yaml` file.
Here is an example overriding the nav item extension with a custom icon component:
```tsx
import {
createFrontendModule,
createNavItemExtension,
} from '@backstage/backstage-plugin-api';
import { MyCustomApiDocsIcon } from './components';
export default createFrontendModule({
pluginId: 'api-docs',
extensions: [
createNavItemExtension({
// It's your choice whether to use the original extension's title or a different one
title: 'APIs',
// Setting a custom icon component
icon: MyCustomApiDocsIcon,
}),
],
});
```
For more information about where to place extension overrides, see the official [documentation](https://backstage.io/docs/frontend-system/architecture/extension-overrides).
#### Apis Explore Page
This `api-docs` plugin installs an "Apis Explore" page extension that helps you visualize apis registered in the Backstage software catalog.
@@ -235,9 +146,6 @@ This `api-docs` plugin installs an "Apis Explore" page extension that helps you
The explore page extension is enable by default when you install the `api-docs` plugin, for disabling it, set the configuration below:
> [!CAUTION]
> The `api-docs` plugin also install a sidebar item that points to this page, remember to disable the nav item as well otherwise it will point to a not found page.
```yaml
# app-config.yaml
# example disabling the apis docs explorer page
-26
View File
@@ -15,7 +15,6 @@ import { ExtensionDataRef } from '@backstage/frontend-plugin-api';
import { ExtensionInput } from '@backstage/frontend-plugin-api';
import { ExternalRouteRef } from '@backstage/core-plugin-api';
import { FilterPredicate } from '@backstage/filter-predicates';
import { IconComponent } from '@backstage/frontend-plugin-api';
import { IconElement } from '@backstage/frontend-plugin-api';
import { JSX as JSX_2 } from 'react';
import { JSXElementConstructor } from 'react';
@@ -472,31 +471,6 @@ const _default: OverridableFrontendPlugin<
filter?: string | FilterPredicate | ((entity: Entity) => boolean);
};
}>;
'nav-item:api-docs': OverridableExtensionDefinition<{
kind: 'nav-item';
name: undefined;
config: {
title: string | undefined;
};
configInput: {
title?: string | undefined;
};
output: ExtensionDataRef<
{
title: string;
icon: IconComponent;
routeRef: RouteRef_2<undefined>;
},
'core.nav-item.target',
{}
>;
inputs: {};
params: {
title: string;
icon: IconComponent;
routeRef: RouteRef_2<undefined>;
};
}>;
'page:api-docs': OverridableExtensionDefinition<{
config: {
initiallySelectedFilter: 'all' | 'owned' | 'starred' | undefined;
+2 -10
View File
@@ -18,7 +18,6 @@ import Grid from '@material-ui/core/Grid';
import {
ApiBlueprint,
NavItemBlueprint,
PageBlueprint,
createFrontendPlugin,
} from '@backstage/frontend-plugin-api';
@@ -39,14 +38,6 @@ import {
EntityContentBlueprint,
} from '@backstage/plugin-catalog-react/alpha';
const apiDocsNavItem = NavItemBlueprint.make({
params: {
title: 'APIs',
routeRef: rootRoute,
icon: () => <AppIcon fontSize="inherit" id="kind:api" />,
},
});
const apiDocsConfigApi = ApiBlueprint.make({
name: 'config',
params: defineParams =>
@@ -76,6 +67,8 @@ const apiDocsExplorerPage = PageBlueprint.makeWithOverrides({
return originalFactory({
path: '/api-docs',
routeRef: rootRoute,
title: 'APIs',
icon: <AppIcon fontSize="inherit" id="kind:api" />,
loader: () =>
import('./components/ApiExplorerPage/DefaultApiExplorerPage').then(
m => (
@@ -222,7 +215,6 @@ export default createFrontendPlugin({
registerApi: registerComponentRouteRef,
},
extensions: [
apiDocsNavItem,
apiDocsConfigApi,
apiDocsExplorerPage,
apiDocsHasApisEntityCard,