diff --git a/.changeset/ninety-cobras-feel.md b/.changeset/ninety-cobras-feel.md new file mode 100644 index 0000000000..e287ef33ed --- /dev/null +++ b/.changeset/ninety-cobras-feel.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Fixed an issue where the entire TechDocs page would re-render when navigating between pages within the same entity's documentation. diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPage/TechDocsReaderPage.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPage/TechDocsReaderPage.tsx index 278eaa9a27..4a2b9e2002 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPage/TechDocsReaderPage.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPage/TechDocsReaderPage.tsx @@ -218,7 +218,8 @@ export const TechDocsReaderPage = (props: TechDocsReaderPageProps) => { ); }, [children, outlet]); - // Show loading indicator when checking for external redirects or about to redirect. + // Show full-page loading spinner when checking for external redirects or about to redirect. + // This replaces the entire page content (header, sidebar, and documentation). if (shouldShowProgress) { return ; } diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPage/useExternalRedirect.ts b/plugins/techdocs/src/reader/components/TechDocsReaderPage/useExternalRedirect.ts index 17e292534b..85fe4c9835 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPage/useExternalRedirect.ts +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPage/useExternalRedirect.ts @@ -43,8 +43,8 @@ export function useExternalRedirect(entityRef: CompoundEntityRef): { const viewTechdocLink = useRouteRef(rootDocsRouteRef); // Create a stable string key for the entity to use as a dependency. - // This ensures we only check for external redirects when the entity changes, - // not on every sub-page navigation within the same entity's TechDocs. + // This ensures the useAsync hook only re-runs when the entity changes, + // preventing redundant API calls during sub-page navigation within the same entity's documentation. const entityKey = useMemo( () => `${entityRef.kind}:${entityRef.namespace}/${entityRef.name}`, [entityRef.kind, entityRef.namespace, entityRef.name], @@ -81,14 +81,16 @@ export function useExternalRedirect(entityRef: CompoundEntityRef): { }, [externalRedirectResult.loading, externalRedirectResult.value, navigate]); // Mark entity as checked once we've determined there's no redirect needed. - // This prevents showing loading states on subsequent sub-page navigation. + // This prevents the entire page from unmounting/remounting (showing Progress spinner) + // on subsequent sub-page navigation within the same entity. useEffect(() => { if (!externalRedirectResult.loading && !externalRedirectResult.value) { checkedEntityRef.current = entityKey; } }, [externalRedirectResult.loading, externalRedirectResult.value, entityKey]); - // Determine if we should show a loading/progress indicator + // Determine if we should show a loading indicator (which replaces the entire page with a Progress spinner). + // Only show it when: 1) checking a new/unchecked entity, or 2) we have a redirect URL and are navigating. const shouldShowProgress = (shouldCheckForRedirect && externalRedirectResult.loading) || !!externalRedirectResult.value;