Skip to content

Commit 0fd858a

Browse files
committed
clean up docs
1 parent a9c1690 commit 0fd858a

File tree

3 files changed

+40
-59
lines changed

3 files changed

+40
-59
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ interface DocsPageContentProps {
1515
breadcrumbs: Breadcrumb[];
1616
}
1717

18+
// DocsPageContent renders the shared docs layout with nav, content, and sidecar.
1819
export default function DocsPageContent({
1920
navTreeData,
2021
docsPageData: {
Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,47 @@ import {
1111
import { docsMetadataTitle } from "@/lib/docs-metadata-title";
1212
import { loadDocsNavTreeData } from "@/lib/fetch-nav";
1313
import { navTreeToBreadcrumbs } from "@/lib/nav-tree-to-breadcrumbs";
14-
import DocsPageContent from "../docs-page-content";
14+
import DocsPageContent from "../DocsPageContent";
1515

16-
export const dynamic = "force-static";
16+
interface DocsRouteProps {
17+
params: Promise<{ path?: string[] }>;
18+
}
19+
20+
// Disable runtime fallback routing so unknown docs paths become 404s.
1721
export const dynamicParams = false;
1822

19-
interface DocsRouteProps {
20-
params: Promise<{ path: string[] }>;
23+
// normalizePathSegments converts an optional catch-all param into a concrete array.
24+
function normalizePathSegments(path: string[] | undefined): string[] {
25+
return path ?? [];
26+
}
27+
28+
// toActivePageSlug maps an optional catch-all route to the docs slug used by loaders.
29+
function toActivePageSlug(path: string[]): string {
30+
return path.length === 0 ? "index" : path.join("/");
2131
}
2232

33+
// isErrorWithCode narrows unknown errors so filesystem codes can be checked safely.
34+
function isErrorWithCode(err: unknown): err is Error & { code: unknown } {
35+
return err instanceof Error && typeof err === "object" && "code" in err;
36+
}
37+
38+
// loadDocsRouteData loads all data needed to render a docs page and its metadata.
2339
async function loadDocsRouteData(path: string[]): Promise<{
2440
navTreeData: NavTreeNode[];
2541
docsPageData: DocsPageData;
2642
breadcrumbs: Breadcrumb[];
2743
}> {
28-
const activePageSlug = path.join("/");
44+
const activePageSlug = toActivePageSlug(path);
2945
const navTreeData = await loadDocsNavTreeData(DOCS_DIRECTORY, activePageSlug);
3046

3147
let docsPageData: DocsPageData;
3248
try {
3349
docsPageData = await loadDocsPage(DOCS_DIRECTORY, activePageSlug);
34-
} catch {
35-
notFound();
50+
} catch (err) {
51+
if (isErrorWithCode(err) && err.code === "ENOENT") {
52+
notFound();
53+
}
54+
throw err;
3655
}
3756

3857
const breadcrumbs = navTreeToBreadcrumbs(
@@ -41,34 +60,43 @@ async function loadDocsRouteData(path: string[]): Promise<{
4160
navTreeData,
4261
activePageSlug,
4362
);
63+
4464
return { navTreeData, docsPageData, breadcrumbs };
4565
}
4666

67+
// generateStaticParams pre-renders the docs index and every nested docs slug.
4768
export async function generateStaticParams(): Promise<
4869
Array<{ path: string[] }>
4970
> {
5071
const docsPageSlugs = await loadAllDocsPageSlugs(DOCS_DIRECTORY);
51-
return docsPageSlugs
72+
const docsPagePaths = docsPageSlugs
5273
.filter((slug) => slug !== "index")
5374
.map((slug) => ({ path: slug.split("/") }));
75+
76+
return [{ path: [] }, ...docsPagePaths];
5477
}
5578

79+
// generateMetadata builds SEO metadata from the resolved docs page and breadcrumbs.
5680
export async function generateMetadata({
5781
params,
5882
}: DocsRouteProps): Promise<Metadata> {
5983
const { path } = await params;
60-
const { docsPageData, breadcrumbs } = await loadDocsRouteData(path);
84+
const { docsPageData, breadcrumbs } = await loadDocsRouteData(
85+
normalizePathSegments(path),
86+
);
6187

6288
return {
6389
title: docsMetadataTitle(breadcrumbs),
6490
description: docsPageData.description,
6591
};
6692
}
6793

94+
// DocsPage renders both /docs and /docs/* routes via a single optional catch-all route.
6895
export default async function DocsPage({ params }: DocsRouteProps) {
6996
const { path } = await params;
70-
const { navTreeData, docsPageData, breadcrumbs } =
71-
await loadDocsRouteData(path);
97+
const { navTreeData, docsPageData, breadcrumbs } = await loadDocsRouteData(
98+
normalizePathSegments(path),
99+
);
72100

73101
return (
74102
<DocsPageContent

src/app/docs/page.tsx

Lines changed: 0 additions & 48 deletions
This file was deleted.

0 commit comments

Comments
 (0)