Skip to content

Commit c8d9768

Browse files
committed
migrate to app router
1 parent 2ca86ad commit c8d9768

File tree

37 files changed

+555
-369
lines changed

37 files changed

+555
-369
lines changed
File renamed without changes.

src/app/docs/[...path]/page.tsx

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import type { Metadata } from "next";
2+
import { notFound } from "next/navigation";
3+
import type { Breadcrumb } from "@/components/breadcrumbs";
4+
import type { NavTreeNode } from "@/components/nav-tree";
5+
import { DOCS_DIRECTORY, DOCS_PAGES_ROOT_PATH } from "@/lib/docs-config";
6+
import {
7+
type DocsPageData,
8+
loadAllDocsPageSlugs,
9+
loadDocsPage,
10+
} from "@/lib/fetch-docs";
11+
import { docsMetadataTitle } from "@/lib/docs-metadata-title";
12+
import { loadDocsNavTreeData } from "@/lib/fetch-nav";
13+
import { navTreeToBreadcrumbs } from "@/lib/nav-tree-to-breadcrumbs";
14+
import DocsPageContent from "../docs-page-content";
15+
16+
export const dynamic = "force-static";
17+
export const dynamicParams = false;
18+
19+
interface DocsRouteProps {
20+
params: Promise<{ path: string[] }>;
21+
}
22+
23+
async function loadDocsRouteData(path: string[]): Promise<{
24+
navTreeData: NavTreeNode[];
25+
docsPageData: DocsPageData;
26+
breadcrumbs: Breadcrumb[];
27+
}> {
28+
const activePageSlug = path.join("/");
29+
const navTreeData = await loadDocsNavTreeData(DOCS_DIRECTORY, activePageSlug);
30+
31+
let docsPageData: DocsPageData;
32+
try {
33+
docsPageData = await loadDocsPage(DOCS_DIRECTORY, activePageSlug);
34+
} catch {
35+
notFound();
36+
}
37+
38+
const breadcrumbs = navTreeToBreadcrumbs(
39+
"Ghostty Docs",
40+
DOCS_PAGES_ROOT_PATH,
41+
navTreeData,
42+
activePageSlug,
43+
);
44+
return { navTreeData, docsPageData, breadcrumbs };
45+
}
46+
47+
export async function generateStaticParams(): Promise<
48+
Array<{ path: string[] }>
49+
> {
50+
const docsPageSlugs = await loadAllDocsPageSlugs(DOCS_DIRECTORY);
51+
return docsPageSlugs
52+
.filter((slug) => slug !== "index")
53+
.map((slug) => ({ path: slug.split("/") }));
54+
}
55+
56+
export async function generateMetadata({
57+
params,
58+
}: DocsRouteProps): Promise<Metadata> {
59+
const { path } = await params;
60+
const { docsPageData, breadcrumbs } = await loadDocsRouteData(path);
61+
62+
return {
63+
title: docsMetadataTitle(breadcrumbs),
64+
description: docsPageData.description,
65+
};
66+
}
67+
68+
export default async function DocsPage({ params }: DocsRouteProps) {
69+
const { path } = await params;
70+
const { navTreeData, docsPageData, breadcrumbs } =
71+
await loadDocsRouteData(path);
72+
73+
return (
74+
<DocsPageContent
75+
navTreeData={navTreeData}
76+
docsPageData={docsPageData}
77+
breadcrumbs={breadcrumbs}
78+
/>
79+
);
80+
}
Lines changed: 10 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,22 @@
11
import Breadcrumbs, { type Breadcrumb } from "@/components/breadcrumbs";
2-
import CustomMDX from "@/components/custom-mdx";
32
import NavTree, { type NavTreeNode } from "@/components/nav-tree";
43
import ScrollToTopButton from "@/components/scroll-to-top";
54
import Sidecar from "@/components/sidecar";
65
import { H1, P } from "@/components/text";
76
import NavFooterLayout from "@/layouts/nav-footer-layout";
8-
import {
9-
type DocsPageData,
10-
loadAllDocsPageSlugs,
11-
loadDocsPage,
12-
} from "@/lib/fetch-docs";
13-
import { loadDocsNavTreeData } from "@/lib/fetch-nav";
14-
import { navTreeToBreadcrumbs } from "@/lib/nav-tree-to-breadcrumbs";
7+
import type { DocsPageData } from "@/lib/fetch-docs";
8+
import { DOCS_PAGES_ROOT_PATH, GITHUB_REPO_URL } from "@/lib/docs-config";
159
import { Pencil } from "lucide-react";
1610
import s from "./DocsPage.module.css";
11+
import customMdxStyles from "@/components/custom-mdx/CustomMDX.module.css";
1712

18-
// This is the location that we expect our docs mdx files to be located,
19-
// relative to the root of the Next.js project.
20-
export const DOCS_DIRECTORY = "./docs";
21-
const GITHUB_REPO_URL = "https://github.com/ghostty-org/website";
22-
// This is the URL path for all of our docs pages
23-
export const DOCS_PAGES_ROOT_PATH = "/docs";
24-
25-
export async function getStaticPaths() {
26-
const docsPageSlugs = await loadAllDocsPageSlugs(DOCS_DIRECTORY);
27-
return {
28-
paths: docsPageSlugs.map((slug: string): StaticPropsParams => {
29-
return {
30-
params: {
31-
path: slug.split("/"),
32-
},
33-
};
34-
}),
35-
fallback: false,
36-
};
37-
}
38-
39-
interface StaticPropsParams {
40-
params: {
41-
path: Array<string>;
42-
};
43-
}
44-
45-
export async function getStaticProps({ params: { path } }: StaticPropsParams) {
46-
const activePageSlug = path.join("/");
47-
const navTreeData = await loadDocsNavTreeData(DOCS_DIRECTORY, activePageSlug);
48-
const docsPageData = await loadDocsPage(DOCS_DIRECTORY, activePageSlug);
49-
const breadcrumbs = navTreeToBreadcrumbs(
50-
"Ghostty Docs",
51-
DOCS_PAGES_ROOT_PATH,
52-
navTreeData,
53-
activePageSlug,
54-
);
55-
return {
56-
props: {
57-
navTreeData,
58-
docsPageData,
59-
breadcrumbs,
60-
},
61-
};
62-
}
63-
64-
interface DocsPageProps {
13+
interface DocsPageContentProps {
6514
navTreeData: NavTreeNode[];
6615
docsPageData: DocsPageData;
6716
breadcrumbs: Breadcrumb[];
6817
}
6918

70-
export default function DocsPage({
19+
export default function DocsPageContent({
7120
navTreeData,
7221
docsPageData: {
7322
title,
@@ -79,29 +28,15 @@ export default function DocsPage({
7928
hideSidecar,
8029
},
8130
breadcrumbs,
82-
}: DocsPageProps) {
31+
}: DocsPageContentProps) {
8332
// Calculate the "Edit in Github" link. If it's not provided
8433
// in the frontmatter, point to the website repo mdx file.
85-
editOnGithubLink = editOnGithubLink
34+
const resolvedEditOnGithubLink = editOnGithubLink
8635
? editOnGithubLink
8736
: `${GITHUB_REPO_URL}/edit/main/${relativeFilePath}`;
8837

8938
return (
90-
<NavFooterLayout
91-
docsNavTree={navTreeData}
92-
meta={{
93-
title:
94-
breadcrumbs.length > 1
95-
? breadcrumbs
96-
.slice(1)
97-
.reverse()
98-
.slice(0, 2)
99-
.map((breadcrumb) => breadcrumb.text)
100-
.join(" - ")
101-
: breadcrumbs[0].text,
102-
description,
103-
}}
104-
>
39+
<NavFooterLayout docsNavTree={navTreeData}>
10540
<div className={s.docsPage}>
10641
<div className={s.sidebar}>
10742
<div className={s.sidebarContentWrapper}>
@@ -130,10 +65,10 @@ export default function DocsPage({
13065
{description}
13166
</P>
13267
</div>
133-
<CustomMDX content={content} />
68+
<div className={customMdxStyles.customMDX}>{content}</div>
13469
<br />
13570
<div className={s.editOnGithub}>
136-
<a href={editOnGithubLink}>
71+
<a href={resolvedEditOnGithubLink}>
13772
Edit on GitHub <Pencil size={14} />
13873
</a>
13974
</div>

src/app/docs/page.tsx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import type { Metadata } from "next";
2+
import { type DocsPageData, loadDocsPage } from "@/lib/fetch-docs";
3+
import { loadDocsNavTreeData } from "@/lib/fetch-nav";
4+
import { navTreeToBreadcrumbs } from "@/lib/nav-tree-to-breadcrumbs";
5+
import { docsMetadataTitle } from "@/lib/docs-metadata-title";
6+
import { DOCS_DIRECTORY, DOCS_PAGES_ROOT_PATH } from "@/lib/docs-config";
7+
import DocsPageContent from "./docs-page-content";
8+
import type { NavTreeNode } from "@/components/nav-tree";
9+
import type { Breadcrumb } from "@/components/breadcrumbs";
10+
11+
export const dynamic = "force-static";
12+
13+
async function loadDocsRouteData(activePageSlug: string): Promise<{
14+
navTreeData: NavTreeNode[];
15+
docsPageData: DocsPageData;
16+
breadcrumbs: Breadcrumb[];
17+
}> {
18+
const navTreeData = await loadDocsNavTreeData(DOCS_DIRECTORY, activePageSlug);
19+
const docsPageData = await loadDocsPage(DOCS_DIRECTORY, activePageSlug);
20+
const breadcrumbs = navTreeToBreadcrumbs(
21+
"Ghostty Docs",
22+
DOCS_PAGES_ROOT_PATH,
23+
navTreeData,
24+
activePageSlug,
25+
);
26+
27+
return { navTreeData, docsPageData, breadcrumbs };
28+
}
29+
30+
export async function generateMetadata(): Promise<Metadata> {
31+
const { docsPageData, breadcrumbs } = await loadDocsRouteData("index");
32+
return {
33+
title: docsMetadataTitle(breadcrumbs),
34+
description: docsPageData.description,
35+
};
36+
}
37+
38+
export default async function DocsIndexPage() {
39+
const { navTreeData, docsPageData, breadcrumbs } =
40+
await loadDocsRouteData("index");
41+
return (
42+
<DocsPageContent
43+
navTreeData={navTreeData}
44+
docsPageData={docsPageData}
45+
breadcrumbs={breadcrumbs}
46+
/>
47+
);
48+
}
File renamed without changes.
Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,41 @@
1+
import type { Metadata } from "next";
2+
import Image from "next/image";
13
import type { NavTreeNode } from "@/components/nav-tree";
24
import SectionWrapper from "@/components/section-wrapper";
35
import { H1, P } from "@/components/text";
46
import NavFooterLayout from "@/layouts/nav-footer-layout";
57
import { fetchLatestGhosttyVersion } from "@/lib/fetch-latest-ghostty-version";
68
import { loadDocsNavTreeData } from "@/lib/fetch-nav";
7-
import Image from "next/image";
9+
import { DOCS_DIRECTORY } from "@/lib/docs-config";
810
import SVGIMG from "../../../public/ghostty-logo.svg";
9-
import { DOCS_DIRECTORY } from "../docs/[...path]";
11+
import ReleaseDownloadPage from "./release-download-page";
12+
import TipDownloadPage from "./tip-download-page";
1013
import s from "./DownloadPage.module.css";
11-
import ReleaseDownloadPage from "./release";
12-
import TipDownloadPage from "./tip";
1314

14-
export async function getStaticProps() {
15-
return {
16-
props: {
17-
latestVersion: await fetchLatestGhosttyVersion(),
18-
docsNavTree: await loadDocsNavTreeData(DOCS_DIRECTORY, ""),
19-
},
20-
};
21-
}
15+
export const dynamic = "force-static";
16+
17+
export const metadata: Metadata = {
18+
title: "Download Ghostty",
19+
description:
20+
"Ghostty is a fast, feature-rich, and cross-platform terminal emulator that uses platform-native UI and GPU acceleration.",
21+
};
2222

23-
export interface DownloadPageProps {
23+
async function loadPageData(): Promise<{
2424
latestVersion: string;
2525
docsNavTree: NavTreeNode[];
26+
}> {
27+
return {
28+
latestVersion: await fetchLatestGhosttyVersion(),
29+
docsNavTree: await loadDocsNavTreeData(DOCS_DIRECTORY, ""),
30+
};
2631
}
2732

28-
export default function DownloadPage({
29-
latestVersion,
30-
docsNavTree,
31-
}: DownloadPageProps) {
33+
export default async function DownloadPage() {
34+
const { latestVersion, docsNavTree } = await loadPageData();
3235
const isTip = process.env.GIT_COMMIT_REF === "tip";
3336

3437
return (
35-
<NavFooterLayout
36-
docsNavTree={docsNavTree}
37-
meta={{
38-
title: "Download Ghostty",
39-
description:
40-
"Ghostty is a fast, feature-rich, and cross-platform terminal emulator that uses platform-native UI and GPU acceleration.",
41-
}}
42-
>
38+
<NavFooterLayout docsNavTree={docsNavTree}>
4339
<main className={s.downloadPage}>
4440
<SectionWrapper>
4541
<div className={s.header}>
@@ -57,15 +53,9 @@ export default function DownloadPage({
5753
)}
5854
</div>
5955
{isTip ? (
60-
<TipDownloadPage
61-
latestVersion={latestVersion}
62-
docsNavTree={docsNavTree}
63-
/>
56+
<TipDownloadPage />
6457
) : (
65-
<ReleaseDownloadPage
66-
latestVersion={latestVersion}
67-
docsNavTree={docsNavTree}
68-
/>
58+
<ReleaseDownloadPage latestVersion={latestVersion} />
6959
)}
7060
</SectionWrapper>
7161
</main>

src/pages/download/release.tsx renamed to src/app/download/release-download-page.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ import { ButtonLink } from "@/components/link";
22
import GenericCard from "@/components/generic-card";
33
import { CodeXml, Download, Package } from "lucide-react";
44
import s from "./DownloadPage.module.css";
5-
import type { DownloadPageProps } from "./index";
5+
6+
interface ReleaseDownloadPageProps {
7+
latestVersion: string;
8+
}
69

710
export default function ReleaseDownloadPage({
811
latestVersion,
9-
docsNavTree,
10-
}: DownloadPageProps) {
12+
}: ReleaseDownloadPageProps) {
1113
return (
1214
<div className={s.downloadCards}>
1315
<GenericCard
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,8 @@ import { ButtonLink } from "@/components/link";
22
import GenericCard from "@/components/generic-card";
33
import { CodeXml, Github, Globe } from "lucide-react";
44
import s from "./DownloadPage.module.css";
5-
import type { DownloadPageProps } from "./index";
65

7-
export default function TipDownloadPage({
8-
latestVersion,
9-
docsNavTree,
10-
}: DownloadPageProps) {
6+
export default function TipDownloadPage() {
117
return (
128
<div className={s.downloadCards}>
139
<GenericCard

0 commit comments

Comments
 (0)