From 528e9ca3c2cf136b907c9fd4a2b675552cc9eab4 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 23 Jul 2026 00:49:59 +0530 Subject: [PATCH] fix: sidebar collapses to first section folder on single-content-dir sites entry-server pre-scoped the page tree to the active content dir before embedding it, but DocsLayout applies filterPageTreeByContentDir again during both SSR and client rendering. On sites with a single content entry the second pass matched the first section folder (all its URLs are under the content prefix) and unwrapped it, so the sidebar showed only that folder's children and dropped every other page. Embed the version-filtered tree instead and leave content-dir scoping to DocsLayout, which is the single place that does it for SSR and client alike. Verified against raystack/meteor docs (35-extractor sidebar): before, the sidebar rendered only the 7 Concepts pages; after, all 73 pages render in their sections. --- packages/chronicle/src/server/entry-server.tsx | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/packages/chronicle/src/server/entry-server.tsx b/packages/chronicle/src/server/entry-server.tsx index dd6fd460..a34e49a2 100644 --- a/packages/chronicle/src/server/entry-server.tsx +++ b/packages/chronicle/src/server/entry-server.tsx @@ -14,9 +14,7 @@ import { getPage, getPageTree, isDraft, getPageNav, loadPageModule, extractFront import { getFirstApiUrl } from '@/lib/api-routes'; import { StatusCodes } from 'http-status-codes'; import { resolvePageAndSlug, resolveDocsRedirect, compactTree } from '@/lib/tree-utils'; -import { filterPageTreeByVersion, filterPageTreeByContentDir } from '@/lib/version-source'; -import { getActiveContentDir } from '@/lib/navigation'; -import { getLatestContentRoots, getVersionContentRoots } from '@/lib/config'; +import { filterPageTreeByVersion } from '@/lib/version-source'; import { isLocalImage, isSvg, buildOptimizedUrl, splitVersion, DEFAULT_WIDTH } from '@/lib/image-utils'; import { QueryClientProvider, QueryClient } from '@tanstack/react-query'; import { useNitroApp } from 'nitro/app'; @@ -82,14 +80,11 @@ export default { const fullTree = await getPageTree(); const versionTree = filterPageTreeByVersion(fullTree, route.version, config); - const contentDirs = route.version.dir - ? getVersionContentRoots(config, route.version.dir) - : getLatestContentRoots(config); - const activeDir = getActiveContentDir(pathname, config); - const scopedTree = contentDirs.length === 1 && activeDir - ? filterPageTreeByContentDir(versionTree, route.version, activeDir) - : versionTree; - const tree = compactTree(scopedTree); + // Content-dir scoping is DocsLayout's job — it runs during both SSR and + // client rendering. Scoping here as well applies the filter twice: the + // second pass unwraps the first section folder and the sidebar loses + // every other page. + const tree = compactTree(versionTree); // SSR redirects for index pages if (route.type === RouteType.ApiIndex) {