* feat(docs): migrate to Geistdocs * fix(chat): align Streamdown highlighter dependencies * feat(docs): switch navbar to Vercel Labs brand Bump @vercel/geistdocs to 2.4.1 and set navbarBrand: "labs" so the docs navbar uses the Vercel Labs logo and links to vercel.com/labs instead of the default OSS branding. * fix(docs): migrate Jev page into the content collection and refresh baseline The merge from main brought the v0.21.0 Jev docs page into the old app/(main)/docs location that the Geistdocs migration had replaced, so /docs/jev appeared in the sitemap but 404'd. Move it to content/docs/jev.mdx with sidebar placement under a new Experimental section, and refresh the docs baseline hashes for the pages whose content changed with the merge (api/core, changelog, skills). * test(docs): refresh core API baseline after main merge
Chat Example
An AI-powered data explorer that streams rich, interactive UI directly into a chat interface. The assistant uses tool calls to fetch real data (weather, GitHub, crypto, Hacker News, web search), then generates a json-render spec that renders inline alongside the conversation using shadcn components, Recharts, and React Three Fiber.
What it shows
- Streaming specs inside chat messages --
pipeJsonRenderon the server merges the AI SDK UI stream with json-render spec patches so text, tool-call indicators, and rendered UI all appear in the correct order within a single message bubble. - ToolLoopAgent with live data -- the agent loops through tool calls (weather, GitHub repos/PRs, crypto prices, Hacker News, web search) to gather real data before generating UI.
- Full catalog/registry stack -- a catalog constrains what the model can produce; the registry maps every component to a real React implementation (shadcn, Recharts charts, R3F 3D scenes).
- State and interactivity --
$state,$bindState, visibility, and actions work inside the streamed spec, so the rendered UI is interactive, not static.
Setup
pnpm install # from the monorepo root
cd examples/chat
cp .env.example .env.local
Set the required environment variables in .env.local:
| Variable | Required | Description |
|---|---|---|
AI_GATEWAY_API_KEY |
Yes | Vercel AI Gateway key (auto-authenticated on Vercel) |
AI_GATEWAY_MODEL |
No | Model identifier, defaults to anthropic/claude-haiku-4.5 |
KV_REST_API_URL |
No | Upstash Redis URL for rate limiting |
KV_REST_API_TOKEN |
No | Upstash Redis token |
RATE_LIMIT_PER_MINUTE |
No | Defaults to 10 |
RATE_LIMIT_PER_DAY |
No | Defaults to 100 |
Rate limiting is a no-op when the Upstash variables are not set.
Run
pnpm dev
# http://chat-demo.json-render.localhost:1355
Requires global portless. The predev script checks for it automatically.
Build checks
From the monorepo root, run pnpm --filter example-chat check-types and pnpm turbo run build --filter=example-chat.
The type check also verifies that Streamdown and @streamdown/code resolve the same Shiki installation. The workspace dependency extension and scoped override keep their exported highlighting types compatible without relying on whichever Shiki version happens to be hoisted.
Files
app/page.tsx-- chat UI withuseChat, message rendering, and inline spec displayapp/api/generate/route.ts-- streams the agent throughpipeJsonRenderwith optional Upstash rate limitinglib/agent.ts--ToolLoopAgentwith system prompt fromexplorerCatalog.prompt()and custom rules for layout, 3D, and interactivitylib/tools/-- tool definitions for weather, GitHub, crypto, Hacker News, and web searchlib/render/catalog.ts-- component catalog (shadcn base + custom metrics, tables, charts, tabs, 3D)lib/render/registry.tsx-- maps catalog types to React components (shadcn, Recharts, R3F)lib/render/renderer.tsx--ExplorerRendererwrappingStateProvider,VisibilityProvider,ActionProvider, andRenderer