mirror of
https://github.com/vercel/chat.git
synced 2026-09-14 18:32:29 +08:00
b7e4bbfbb0
## Summary
Upgrades the chat-sdk.dev docs app from `@vercel/geistdocs` **1.20.4 →
1.22.0** (published 2026-08-21, Apache-2.0) and `next` **16.2.11 →
16.3.1**, following the bundled 1.22.0 template as the source of truth.
The target release includes all of the behavior-changing PRs for this
round:
- vercel/geistdocs#245 — require Next.js 16.3, scaffold 16.3.1, drop the
dev filesystem-cache flag (shipped in 1.21.1)
- vercel/geistdocs#246 — Cache Components across Geistdocs
- vercel/geistdocs#249 — Partial Prefetching + instant docs navigation
- vercel/geistdocs#250 — stable Next 16.3 APIs, retryable page/Ask AI
error boundaries, full prefetch of package links, no generic page shell
- vercel/geistdocs#251 — tree sidebar preserves scroll position on
folder toggles
## Adapter and configuration changes
- `next.config.ts`: `cacheComponents: true`, `partialPrefetching: true`;
removed `experimental.turbopackFileSystemCacheForDev` (default in 16.3).
Redirects, `/sitemap.xml` rewrite, and image config unchanged.
- New `lib/geistdocs/root-params.ts`; all layouts read `[lang]` via
`next/root-params` instead of `params`. Route handlers keep
route-context `params`.
- Root layout gains `generateStaticParams` returning every configured
language (`en`) — home (`/`), `/adapters`, and `/resources` now
prerender statically (previously dynamic).
- Route adapters no longer re-export `revalidate`/`dynamic` from package
factories (`agents.md`, `sitemap.md`, `llms.mdx`), and custom routes
drop their own `revalidate` exports (`llms.txt`, `llms-full.txt`,
`adapters.mdx`, `rss.xml`, `resources`).
- `llms.mdx` adopts the template form: `sources: [geistdocsSource]` +
`notFound: {}`, enabling smart agent-readable 404/410 responses with
real HTTP statuses.
- `rss.xml` migrated to the template's `"use cache"` +
`cacheLife("max")` form with `getPublicPath` base-path handling.
- `resources` page: `revalidate = 86400` → `"use cache"` +
`cacheLife("days")` (same 1-day lifetime).
- App-owned data fetching moved off `next: { revalidate }` (unsupported
under Cache Components): GitHub README fetches and homepage OSS stats
now use `"use cache"` + `cacheLife("hours")`.
- Homepage Shiki highlighting (`Demo`, `CodePreview`, `highlightCode`)
runs inside `"use cache"` scopes — Shiki reads `Date.now()` internally,
which otherwise fails prerendering.
- App-owned links to statically generated docs pages get
`prefetch={true}` (platform grid, feature matrix, adapter slug list,
"Visit Documentation") per the template's agent guidance; package-owned
sidebar/prev-next links already prefetch fully in 1.22.0.
- `Analytics`/`SpeedInsights` moved into
`components/geistdocs/provider.tsx` per the template.
- CSS: `styles/geistdocs.css` now imports `@vercel/geistdocs/theme.css`
(self-sourcing package dist/streamdown) instead of layering on
`styles.css` from `global.css`; updated the mobile breadcrumb selector
for the new package DOM; kept the site-specific shadcn tokens, dark
background-scale override, prose, TOC, and streamdown fixes.
- Added `apps/docs/AGENTS.md` capturing the packaged-architecture
conventions (cache-components rules, root-params, markdown contract,
proxy mappings).
## PR #251 (tree sidebar scroll) verification
The fix is package-internal (`manualToggleRef` in `SidebarTree`); no
consumer change is needed. This site's sidebars render no collapsible
folder rows (content uses spread folders, `...api` etc.), so I verified
the shipped behavior against the bundled 1.22.0 template with
`sidebarMode="tree"` enabled locally: expanding/collapsing a folder
preserves the exact sidebar scroll position (772 → 772), and a route
change into a collapsed folder still scrolls the active item into view.
8/8 checks pass.
## Static-generation coverage
Production build: 290/290 static pages generated. Every intended
parameter tuple is prerendered with complete content (verified H1/body
in emitted HTML):
- `/en` home, `/en/adapters` listing, `/en/resources` — now fully static
(were `ƒ` on main)
- `/en/docs/*` — 45 pages, complete static HTML + one generic
`[[...slug]]` fallback entry (allowed)
- `/en/adapters/{official,community,vendor-official}/*` — 44 detail
pages + `/en/adapters.mdx/*` markdown for all 44
- `/en/sitemap.md` — SSG
Intentional contract differences (match the 1.22.0 template's own build
output):
- OG image routes (`/og/[...slug]`, adapter `*/og`) render on demand
under Cache Components instead of build-time SSG; Next 16.3 caches the
rendered image per route. URLs and content types verified unchanged.
- `llms.txt`, `llms-full.txt`, `llms.mdx`, `rss.xml`, `agents.md` remain
on-demand route handlers (same as main); `agents.md` reads the request
origin by package design.
- Unknown HTML routes: browsers receive the docs shell with 200 before
not-found UI resolves; crawlers get a real 404. Machine-readable unknown
routes return the new smart 404 body with real 404 status and
`X-Robots-Tag: noindex`.
## Lockfile
`pnpm-lock.yaml` delta: the `docs` importer's `@vercel/geistdocs`
(1.20.4 → 1.22.0) and `next` (16.2.11 → 16.3.1) bumps, their
peer-context re-resolutions, and one mechanical re-keying of `@swc/core`
peer contexts to include `@swc/helpers` across existing entries (no
version changes outside the docs app). Verified with `pnpm install
--frozen-lockfile`.
## Test results
- `pnpm install --frozen-lockfile` ✓
- `pnpm check` ✓ (1 pre-existing warning in untouched
`lib/read-more.ts`)
- `pnpm typecheck` — 43/43 ✓
- `pnpm knip` ✓, `pnpm konsistent` ✓
- `pnpm test` — 47/47 turbo tasks ✓
- Clean production build (removed `.next`/`.source`) ✓ 290/290
- Production-server (`next start`) contract checks: HTML docs,
`.md`/`.mdx`, `Accept: text/markdown`, agent-UA negotiation, `llms.txt`,
`llms-full.txt`, `sitemap.md`, `agents.md`, `/.well-known/mcp.json`
(intentional 404), `rss.xml`, `robots.txt`, `/sitemap.xml` rewrite, OG
images, `AGENTS.md`, all redirects (308s), `/api/search` JSON and not
rewritten as markdown, `/docs.md` section root ✓
- Browser checks (Playwright, Chrome, `next start`) — 16/16: instant
sidebar + prev/next client navigation with complete content and no
loading shell, single visible H1 (Activity-preserved routes stay
hidden), Copy Page, page actions menu, search → result navigation, Ask
AI panel with suggestions, theme switch (dark applies the site's
background scale), mobile navbar menu and docs sheet navigation, unknown
page shows not-found UI, zero console/page errors and failed requests
- Ask AI scoped failure: with no local AI Gateway credentials the chat
surfaces the error, the surrounding page stays intact, and resubmission
retries cleanly
- Visual parity screenshots vs production (home/docs/adapters, light +
dark) match
## Preview
- Preview:
https://chat-git-richardhaines-geistdocs-122-upgrade.vercel.sh —
deployment **Ready**, build passed on Vercel.
- The preview sits behind Vercel SSO (Fork Protection), so automated
route checks aren't possible without a bypass token; please spot-check
through SSO: `/docs/getting-started`, `/docs/getting-started.md`,
`/adapters`, `/llms.txt`, and a client navigation between docs pages.
Signed-off-by: molebox <rich@vercel.com>
7.8 KiB
7.8 KiB
Geistdocs agent instructions
This app (chat-sdk.dev) uses the packaged Geistdocs architecture. The @vercel/geistdocs package owns shared runtime behavior; this app owns local content, configuration, adapters, and site-specific routes.
Use these instructions when an AI coding agent edits this app.
Architecture
- Runtime features come from
@vercel/geistdocs, including the docs page renderer, layout helpers, MDX components, search, Ask AI, markdown routes, proxy helpers, and source helpers. @vercel/geistdocsowns the Ask AI client, server route behavior, and AI SDK v6 runtime dependencies. Do not fork package internals to fit an older app-levelaiversion.- Local files are user-owned adapters. They should stay thin and call public package exports from
@vercel/geistdocs/*. - Do not copy package internals into the app to make a customization. Prefer configuring an adapter file or upgrading
@vercel/geistdocs. - Do not deep import from
@vercel/geistdocs/distor edit files innode_modules/@vercel/geistdocs. - Do not edit generated directories such as
.source/,.next/,node_modules/, or build output.
Package docs for agents
- When package API behavior is unclear, read the installed package docs in
node_modules/@vercel/geistdocs/docsbefore guessing. - Start with
node_modules/@vercel/geistdocs/docs/agents.mdandnode_modules/@vercel/geistdocs/docs/sitemap.mdto identify the relevant focused page. - Use
node_modules/@vercel/geistdocs/docs/pages/*.mdfor task-specific guidance andnode_modules/@vercel/geistdocs/docs/llms.txtonly when you need broad package context. - These package docs are read-only generated artifacts. Do not edit files under
node_modules/@vercel/geistdocs; change local adapter files or update the package instead.
Common edit targets
| Task | Edit |
|---|---|
Configure site title, logo, nav, GitHub links, AI prompt, suggestions, translations, basePath, siteId, or agent-readiness metadata |
geistdocs.tsx |
| Add or update documentation pages | content/docs/**/*.mdx |
| Add or update adapter listing pages | content/adapters/**/*.mdx and adapters.json |
| Control sidebar order, groups, and folder labels | content/docs/meta.json, content/adapters/meta.json |
| Give a page a shorter navigation label | Set navTitle in the page's frontmatter |
| Override MDX components | components/geistdocs/mdx-components.tsx |
| Wrap the site provider, analytics, or global client behavior | components/geistdocs/provider.tsx |
| Customize the docs layout shells | components/geistdocs/docs-layout.tsx, components/geistdocs/adapters-docs-layout.tsx, components/geistdocs/home-layout.tsx |
| Configure the Fumadocs source adapters | lib/geistdocs/source.ts, lib/geistdocs/adapters-source.ts |
| Configure Fumadocs collections and source-safe MDX processing | source.config.ts |
| Configure the docs page renderer | app/[lang]/docs/[[...slug]]/page.tsx |
| Configure AI-readable markdown output | app/[lang]/agents.md/route.ts, app/[lang]/llms.txt/route.ts (curated index), app/[lang]/llms-full.txt/route.ts, app/[lang]/llms.mdx/[[...slug]]/route.ts, app/[lang]/adapters.mdx/[[...slug]]/route.ts, app/[lang]/sitemap.md/route.ts |
| Configure chat or search APIs | app/api/chat/route.ts, app/api/search/route.ts |
| Add request handling before or after Geistdocs routing | proxy.ts |
| Edit the marketing home page | app/[lang]/(home)/** |
| Edit shared styles | app/global.css, app/styles/geistdocs.css |
Content guidelines
- Put docs in
content/docsand adapter pages incontent/adapters. - Add each new page to the directory's
meta.jsonso it appears in the sidebar. - Use MDX frontmatter with at least
titleanddescriptionfor documentation pages. SetnavTitleonly when the navigation label should differ from the page heading. - Keep slugs stable unless the task explicitly includes redirects or link updates.
- Use
CopyPromptwhen a page should give readers a prompt they can copy into a coding agent.
Routing and proxy guidelines
- Keep App Router route files as thin adapters around package helpers such as
createDocsPage,createChatRoute,createProxy, and the route factories under@vercel/geistdocs/routes/*. - Keep
cacheComponents: trueandpartialPrefetching: trueinnext.config.ts. Do not exportdynamic,revalidate, orfetchCachefrom App Router pages or route handlers; package route factories may still return them, so destructure onlyGETandgenerateStaticParams. Cache custom data with"use cache"andcacheLifeinstead. - Read
[lang]fromnext/root-params(vialib/geistdocs/root-params.ts) in Server Components. Keep route contextparamsin Route Handlers and Server Actions. - Keep
generateStaticParamsfor the rootlangparam inapp/[lang]/layout.tsx; it must return every configured language. - Use
prefetch={true}for app-owned links to fully static documentation pages so navigation does not stop at the generic route shell. - Keep
export const configinproxy.tsas a static object. Next.js must parse proxy matchers at build time. - Use proxy matcher exclusions that only match
/apiand/api/..., such asapi(?:/|$). Do not exclude broad prefixes likeapi, because that also excludes routes such as/api-reference. - Preserve markdown negotiation unless the task explicitly changes AI-readable output. This site serves
/agents.md,/llms.txt,/llms-full.txt,/sitemap.md, and per-page Markdown for.md,.mdx,Accept: text/markdown, and AI-agent requests across both the/docsand/adaptersfamilies. - When adding custom proxy behavior, prefer
before,after, andmarkdownRoutesoptions oncreateProxyinstead of replacing the proxy. This site maps/docs/*and/adapters/*explicitly because the two families use different markdown route handlers. llms.txtis a curated index with section descriptions; do not replace it with the concatenatedcreateLlmsRouteoutput.llms-full.txtserves the concatenated corpus./.well-known/mcp.jsonintentionally returns 404; no MCP server is configured for this site./sitemap.xmlis served by an external rewrite innext.config.ts, not an app route.
Ask AI guidelines
- Leave
GEISTDOCS_CHAT_PROXY_URLunset to use the default AI Gateway path. The route adapter pins the model withcreateChatRoute({ model }). - Geistdocs Ask AI targets AI SDK v6:
aiv6 and@ai-sdk/reactv3. Keep those dependencies on the package-pinned versions unless a@vercel/geistdocsrelease changes them. - Keep
app/api/chat/route.tsas a thin adapter aroundcreateChatRoute.
Package updates
- Use
pnpm exec geistdocs updateto update the@vercel/geistdocsdependency. It does not overwrite local adapter files — diff them against the bundled template innode_modules/@vercel/geistdocs/templateafter every upgrade. - Review dependency changes and run the verification commands before committing an update.
Commands
Run from the repository root:
- Start development:
pnpm --filter docs dev - Build for production:
pnpm --filter docs build - Start the built app:
pnpm --filter docs start - Regenerate Fumadocs output after dependency installation:
pnpm --filter docs postinstall
Verification
- Run
pnpm --filter docs buildafter changing routes, config, source setup, MDX components, or package versions, and confirm every known docs and adapter URL still has a complete static prerender. - Run
pnpm --filter docs startand open the changed pages when visual layout, navigation, or MDX rendering changes. - Check both
/docsand AI-readable routes such as/agents.md,/llms.txt,/sitemap.md, or a page-level.mdURL when changing content routing or proxy behavior. - Confirm no secrets were added to source files. Use
.env.localfor local values and keep it out of Git.