Skip to content

Commit 0adff00

Browse files
committed
Add static Vercel docs route
1 parent ac546fc commit 0adff00

6 files changed

Lines changed: 817 additions & 17 deletions

File tree

rust-rewrite/docs-site-strategy.md

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@
22

33
## Recommendation
44

5-
Keep the product docs and the landing page as separate surfaces:
5+
Build the product docs and landing page as one Vercel-hosted Next.js site:
66

7-
- `docs/`: Mintlify documentation source of truth.
8-
- `site/`: Vercel-hosted Next.js landing page.
7+
- `site/`: Vercel-hosted Next.js app for the landing page and statically rendered docs.
8+
- `site/content/docs/`: target long-term docs content source, migrated from the current `docs/` tree.
9+
- `site/lib/docs/` and `site/components/docs/`: target docs loader, navigation, search index generation, and MDX component shims.
910
- `rust-rewrite/skill-prototype/graph-sitter/`: draft Codex skill artifact until the package and docs are release-ready.
1011

11-
The landing page should explain Graph-sitter in one screen and route users to the docs. The docs should carry setup, CLI, API, Rust backend, JS/TS, codemod, correctness, and benchmark details. This avoids coupling generated API reference pages and long-form guides to a small marketing app.
12+
The landing page should explain Graph-sitter in one screen. The docs should live in the same app under static routes and carry setup, CLI, API, Rust backend, JS/TS, codemod, correctness, and benchmark details. This gives us full control over layout, search, examples, interactive demos, custom benchmarking views, and future skill distribution pages.
1213

13-
If the team later decides "docs site on Vercel" means moving docs rendering off Mintlify, treat that as a separate migration. The likely path would be a docs app under `site/docs` or `apps/docs` using MDX, with a scripted import from `docs/`. Do not start there unless Mintlify becomes a blocker.
14+
Mintlify should be treated as the legacy docs source/renderer, not the target platform. Keep the current `docs/` content as migration input until the Next docs renderer has parity, then retire Mintlify-specific config and CI.
1415

1516
## Current Repo Signals
1617

@@ -29,9 +30,10 @@ If the team later decides "docs site on Vercel" means moving docs rendering off
2930
Recommended public URLs:
3031

3132
```text
32-
https://graph-sitter.com -> Vercel landing app rooted at site/
33+
https://graph-sitter.com -> Vercel Next app landing page
34+
https://graph-sitter.com/docs -> Vercel statically rendered docs
3335
https://www.graph-sitter.com -> Vercel redirect or alias to the apex
34-
https://docs.graph-sitter.com -> Mintlify docs rooted at docs/
36+
https://docs.graph-sitter.com -> Vercel alias or redirect to /docs
3537
```
3638

3739
Landing page responsibilities in `site/`:
@@ -43,7 +45,7 @@ Landing page responsibilities in `site/`:
4345
- cautious `uvx graph-sitter ...` preview
4446
- links to docs and GitHub
4547

46-
Docs responsibilities in `docs/`:
48+
Docs responsibilities in the Vercel app:
4749

4850
- install and setup
4951
- parse command and JSON output
@@ -56,6 +58,35 @@ Docs responsibilities in `docs/`:
5658
- generated API reference
5759
- Codex skill installation and usage once published
5860

61+
Recommended route shape:
62+
63+
```text
64+
site/app/page.tsx -> landing page
65+
site/app/docs/[[...slug]]/page.tsx -> static docs renderer
66+
site/app/api-reference/[[...slug]] -> optional alias or docs section
67+
site/content/docs/**/*.mdx -> migrated docs content
68+
site/content/nav.ts -> navigation source replacing mint.json
69+
site/components/docs/*.tsx -> MDX shims and docs UI
70+
site/lib/docs/*.ts -> content loading, frontmatter, static params, search manifest
71+
```
72+
73+
Use `generateStaticParams` and `dynamicParams = false` for docs routes so Vercel pre-renders every docs page. A full static export can be evaluated later, but regular Vercel static generation is enough for launch and keeps room for future dynamic features such as hosted examples or generated benchmark views.
74+
75+
## Migration Plan From Mintlify
76+
77+
The current `docs/` tree is a useful content seed, but it contains Mintlify-specific navigation and MDX components. Migrate deliberately:
78+
79+
1. Inventory MDX component usage in `docs/**/*.mdx`.
80+
2. Implement local component shims in `site/components/docs/` for high-use components such as `Note`, `Card`, `CardGroup`, `Param`, `ResponseField`, and code blocks.
81+
3. Convert `docs/mint.json` navigation into a typed `site/content/nav.ts` or `site/content/nav.json`.
82+
4. Move or copy content into `site/content/docs/` so the Vercel project is self-contained.
83+
5. Add a build-time docs loader that parses frontmatter, resolves slugs, renders MDX, and emits a search manifest.
84+
6. Port generated API reference pages or replace them with a generator that writes Vercel-compatible MDX.
85+
7. Add redirects from old slugs to new slugs before domain cutover.
86+
8. Remove Mintlify CI only after Next docs build proves parity on all docs pages.
87+
88+
Do not depend on files outside `site/` at Vercel build time unless the project root is deliberately changed to the repository root. The lower-risk target is a self-contained `site/` app with docs content underneath `site/content/docs/`.
89+
5990
## Accuracy Contract For Docs
6091

6192
Setup docs must be explicit about three workflows:
@@ -131,7 +162,12 @@ Runtime Env Vars: none required today
131162
Production Branch: integrator-approved trunk branch
132163
```
133164

134-
No checked-in `vercel.json` is required for the current app if Vercel project settings define `site` as the root directory. Add `site/vercel.json` only if the project needs repo-portable settings such as redirects, headers, or pinned framework behavior.
165+
No checked-in `vercel.json` is required for the current app if Vercel project settings define `site` as the root directory. Once docs move to Vercel, add `site/vercel.json` or Next redirects if needed for:
166+
167+
- `docs.graph-sitter.com` domain routing.
168+
- old Mintlify slug redirects.
169+
- canonical `/docs` paths.
170+
- long-cache headers for generated static assets and search indexes.
135171

136172
Read-only/project setup checks:
137173

@@ -165,7 +201,7 @@ Production cutover requires explicit approval:
165201

166202
- attach `graph-sitter.com` to the Vercel landing project
167203
- attach or redirect `www.graph-sitter.com`
168-
- keep `docs.graph-sitter.com` pointed at docs hosting
204+
- attach or redirect `docs.graph-sitter.com` to the Vercel docs routes
169205
- update `hatch.toml` documentation URL if final docs URL differs from current metadata
170206

171207
Do not run `vercel deploy --prod`, promote a deployment, or attach domains from a subagent task.
@@ -224,7 +260,15 @@ Rules:
224260
### Docs Architecture
225261

226262
- [x] Create docs/site strategy. owner: docs-vercel-subagent. Result: `rust-rewrite/docs-site-strategy.md`.
227-
- [ ] Decide whether docs stay on Mintlify for launch or migrate to Vercel MDX. owner: unclaimed.
263+
- [x] Decide whether docs stay on Mintlify for launch or migrate to Vercel MDX. owner: user. Result: target is Vercel/Next with statically rendered docs; Mintlify is legacy migration input.
264+
- [x] Design the Vercel docs content tree under `site/content/docs`. owner: codex. Result: added typed seed docs content in `site/content/docs/pages.ts` plus route/nav helpers for static docs pages.
265+
- [ ] Inventory Mintlify-specific MDX components used by `docs/**/*.mdx`. owner: unclaimed.
266+
- [ ] Build local MDX component shims for the migrated docs renderer. owner: unclaimed.
267+
- [ ] Convert `docs/mint.json` navigation into a Vercel docs nav source. owner: unclaimed.
268+
- [x] Create a static docs route in the Next app with `generateStaticParams`. owner: codex. Result: `site/app/docs/[[...slug]]/page.tsx` prerenders `/docs` plus setup, uvx, Rust status, parity, benchmark, and TypeScript support pages with `dynamicParams = false`.
269+
- [ ] Generate a static client-side search manifest for docs pages. owner: unclaimed.
270+
- [ ] Port or regenerate API reference pages into Vercel-compatible MDX. owner: unclaimed.
271+
- [ ] Add redirects for old Mintlify docs slugs before domain cutover. owner: unclaimed.
228272
- [ ] Add a docs release gate checklist to `rust-rewrite/strategy.md` or keep this file as the docs ledger. owner: unclaimed.
229273
- [x] Audit `docs/introduction/installation.mdx` against current `uv run`, `uv tool install`, and `uvx` behavior. owner: codex. Result: installation docs now distinguish installed tool, local source, published-package `uvx`, and branch-built wheel validation.
230274
- [x] Add or update a dedicated `docs/cli/uvx.mdx` page with release-gated package guidance. owner: codex. Result: added `docs/cli/uvx.mdx` for parse, run, transform, backend, safety, `--subdir`, and release-gate workflows.
@@ -236,17 +280,17 @@ Rules:
236280

237281
- [ ] Review `site/app/page.tsx` copy for release-gated claims before the first public preview. owner: unclaimed.
238282
- [ ] Add a landing-page CTA to the exact docs quickstart once the docs URL is final. owner: unclaimed.
239-
- [ ] Verify `site` builds from a clean install with Node 22. owner: unclaimed.
283+
- [x] Verify `site` builds from a clean install with Node 22. owner: codex. Result: `PATH="$HOME/.nvm/versions/node/v22.19.0/bin:$PATH" npm ci && npm run build` passed and generated the static docs route.
240284
- [ ] Add landing-page screenshots or visual QA notes before production domain cutover. owner: unclaimed.
241285

242286
### Vercel
243287

244288
- [ ] Link or create the Vercel project with root directory `site`. owner: unclaimed.
245289
- [ ] Pull preview env with `vercel pull --cwd site --environment=preview --yes`. owner: unclaimed.
246-
- [ ] Run a preview deploy for review only. owner: unclaimed.
290+
- [ ] Run a preview deploy for review only after the static docs route builds. owner: unclaimed.
247291
- [ ] Record the preview URL in this file or the integrator thread. owner: unclaimed.
248-
- [ ] Confirm `docs.graph-sitter.com` hosting before apex cutover. owner: unclaimed.
249-
- [ ] Attach `graph-sitter.com` and `www.graph-sitter.com` only after explicit approval. owner: blocked-pending-approval.
292+
- [ ] Confirm `docs.graph-sitter.com` routing to Vercel docs before apex cutover. owner: unclaimed.
293+
- [ ] Attach `graph-sitter.com`, `www.graph-sitter.com`, and `docs.graph-sitter.com` only after explicit approval. owner: blocked-pending-approval.
250294

251295
### Skill
252296

@@ -267,5 +311,6 @@ Rules:
267311

268312
- [ ] Ensure PyPI package metadata points to the final docs and landing URLs. owner: unclaimed.
269313
- [ ] Ensure the public setup path does not claim `uvx graph-sitter ...` until clean package validation passes. owner: unclaimed.
270-
- [x] Add a docs validation CI or release gate for `mintlify validate`. owner: codex. Result: `.github/workflows/docs-validate.yml` runs Mintlify validate and broken-link checks for docs changes.
314+
- [ ] Replace Mintlify docs validation CI with a Next docs build/link validation gate after migration. owner: unclaimed.
315+
- [x] Add a legacy docs validation CI or release gate for `mintlify validate`. owner: codex. Result: `.github/workflows/docs-validate.yml` runs Mintlify validate and broken-link checks for docs changes until Vercel docs replace it.
271316
- [x] Add a site build CI or release gate for `npm --prefix site ci && npm --prefix site run build`. owner: codex. Result: `.github/workflows/site-build.yml` installs from `site/package-lock.json` and runs the Next.js production build for landing-site changes.

site/app/docs/[[...slug]]/page.tsx

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import type { Metadata } from "next";
2+
import Link from "next/link";
3+
import { notFound } from "next/navigation";
4+
import { docsNav } from "../../../content/nav";
5+
import {
6+
docsHref,
7+
docsPages,
8+
docsStaticParams,
9+
getDocsPage,
10+
type DocsBlock
11+
} from "../../../content/docs/pages";
12+
13+
type DocsPageProps = {
14+
params: Promise<{
15+
slug?: string[];
16+
}>;
17+
};
18+
19+
export const dynamicParams = false;
20+
21+
export function generateStaticParams() {
22+
return docsStaticParams();
23+
}
24+
25+
export async function generateMetadata({
26+
params
27+
}: DocsPageProps): Promise<Metadata> {
28+
const { slug } = await params;
29+
const page = getDocsPage(slug);
30+
if (!page) {
31+
return {
32+
title: "Docs | Graph-sitter"
33+
};
34+
}
35+
return {
36+
title: `${page.title} | Graph-sitter Docs`,
37+
description: page.description
38+
};
39+
}
40+
41+
export default async function DocsPage({ params }: DocsPageProps) {
42+
const { slug } = await params;
43+
const page = getDocsPage(slug);
44+
if (!page) {
45+
notFound();
46+
}
47+
48+
const pageIndex = docsPages.findIndex((candidate) => candidate.slug === page.slug);
49+
const previous = pageIndex > 0 ? docsPages[pageIndex - 1] : undefined;
50+
const next = pageIndex < docsPages.length - 1 ? docsPages[pageIndex + 1] : undefined;
51+
52+
return (
53+
<main className="docs-shell">
54+
<header className="docs-topbar">
55+
<Link className="brand" href="/">
56+
<span className="brand-mark" aria-hidden="true">
57+
GS
58+
</span>
59+
<span>Graph-sitter</span>
60+
</Link>
61+
<nav className="nav-links" aria-label="Docs links">
62+
<Link href="/">Landing</Link>
63+
<Link href="https://github.com/codegen-sh/graph-sitter">GitHub</Link>
64+
</nav>
65+
</header>
66+
67+
<div className="docs-layout">
68+
<aside className="docs-sidebar" aria-label="Docs navigation">
69+
{docsNav.map((group) => (
70+
<section className="docs-nav-group" key={group.title}>
71+
<h2>{group.title}</h2>
72+
<ul>
73+
{group.items.map((item) => (
74+
<li key={item.slug}>
75+
<Link
76+
className={item.slug === page.slug ? "is-active" : undefined}
77+
href={docsHref(item.slug)}
78+
>
79+
{item.title}
80+
</Link>
81+
</li>
82+
))}
83+
</ul>
84+
</section>
85+
))}
86+
</aside>
87+
88+
<article className="docs-article">
89+
<div className="docs-status">{page.status}</div>
90+
<h1>{page.title}</h1>
91+
<p className="docs-description">{page.description}</p>
92+
93+
{page.sections.map((section) => (
94+
<section className="docs-section" key={section.title}>
95+
<h2>{section.title}</h2>
96+
{section.blocks.map((block, index) => (
97+
<DocsBlockView block={block} key={`${section.title}-${index}`} />
98+
))}
99+
</section>
100+
))}
101+
102+
<nav className="docs-pagination" aria-label="Docs pagination">
103+
{previous ? (
104+
<Link href={docsHref(previous.slug)}>
105+
<span>Previous</span>
106+
{previous.navTitle ?? previous.title}
107+
</Link>
108+
) : (
109+
<span />
110+
)}
111+
{next ? (
112+
<Link href={docsHref(next.slug)}>
113+
<span>Next</span>
114+
{next.navTitle ?? next.title}
115+
</Link>
116+
) : (
117+
<span />
118+
)}
119+
</nav>
120+
</article>
121+
</div>
122+
</main>
123+
);
124+
}
125+
126+
function DocsBlockView({ block }: { block: DocsBlock }) {
127+
if (block.type === "paragraph") {
128+
return <p>{block.text}</p>;
129+
}
130+
131+
if (block.type === "list") {
132+
return (
133+
<ul className="docs-list">
134+
{block.items.map((item) => (
135+
<li key={item}>{item}</li>
136+
))}
137+
</ul>
138+
);
139+
}
140+
141+
return (
142+
<pre className="docs-code">
143+
<code>{block.code}</code>
144+
</pre>
145+
);
146+
}

0 commit comments

Comments
 (0)