core-plugin-api: avoid adding api context requirement for useApp and useRouteRef

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2025-11-23 17:43:19 +01:00
parent 395ff1c43b
commit 338c89936c
2 changed files with 28 additions and 11 deletions
+16 -7
View File
@@ -25,6 +25,7 @@ import {
Progress,
createFrontendPlugin,
FrontendPlugin,
ApiHolder,
} from '@backstage/frontend-plugin-api';
import {
AppComponents,
@@ -75,26 +76,34 @@ function toNewPlugin(plugin: BackstagePlugin): FrontendPlugin {
});
}
function useOptionalApiHolder(): ApiHolder | undefined {
try {
return useApiHolder();
} catch {
return undefined;
}
}
/**
* React hook providing {@link AppContext}.
*
* @public
*/
export const useApp = (): AppContextV1 => {
const apiHolder = useApiHolder();
const appTreeApi = apiHolder.get(appTreeApiRef);
const apiHolder = useOptionalApiHolder();
const appTreeApi = apiHolder?.get(appTreeApiRef);
const iconsApi = apiHolder?.get(iconsApiRef);
const versionedContext = useVersionedContext<{ 1: AppContextV1 }>(
'app-context',
);
const newAppContext = useMemo<AppContextV1 | null>(() => {
const newAppContext = useMemo<AppContextV1 | undefined>(() => {
if (!appTreeApi) {
return null;
return undefined;
}
const iconsApi = apiHolder.get(iconsApiRef);
if (!iconsApi) {
return null;
return undefined;
}
const { tree } = appTreeApi.getTree();
@@ -152,7 +161,7 @@ export const useApp = (): AppContextV1 => {
};
},
};
}, [appTreeApi, apiHolder]);
}, [appTreeApi, iconsApi]);
if (newAppContext) {
return newAppContext;
@@ -18,8 +18,9 @@ import { useMemo } from 'react';
import { matchRoutes, useLocation } from 'react-router-dom';
import { useVersionedContext } from '@backstage/version-bridge';
import {
RouteResolutionApi,
routeResolutionApiRef,
useApiHolder,
useApi,
} from '@backstage/frontend-plugin-api';
import {
AnyParams,
@@ -42,6 +43,14 @@ export interface RouteResolver {
): RouteFunc<Params> | undefined;
}
function useRouteResolutionApi(): RouteResolutionApi | undefined {
try {
return useApi(routeResolutionApiRef);
} catch {
return undefined;
}
}
/**
* React hook for constructing URLs to routes.
*
@@ -90,8 +99,7 @@ export function useRouteRef<Params extends AnyParams>(
| ExternalRouteRef<Params, any>,
): RouteFunc<Params> | undefined {
const { pathname } = useLocation();
const apiHolder = useApiHolder();
const routeResolutionApi = apiHolder.get(routeResolutionApiRef);
const routeResolutionApi = useRouteResolutionApi();
const versionedContext = useVersionedContext<{ 1: RouteResolver }>(
'routing-context',
);
@@ -104,7 +112,7 @@ export function useRouteRef<Params extends AnyParams>(
}
try {
return routeResolutionApi.resolve(routeRef, {
return routeResolutionApi?.resolve(routeRef, {
sourcePath: pathname,
});
} catch {