Imported from akillness/jeo-skills (
.agent-skills/chatbot-template/SKILL.md). Install upstream withnpx skills add akillness/jeo-skills --skill chatbot-template. Copyright stays with the author.
chatbot-template
chatbot-template is shadcn/ui's minimal, opinionated Next.js starter for an AI
chatbot: streaming markdown responses (react-markdown + shadcn/typeset),
typed tool calling, provider-native web search, and a human-in-the-loop
ask_user questionnaire the model can trigger to ask clarifying questions.
It deploys to Vercel with zero configuration — the AI Gateway authenticates
automatically via OIDC — or runs locally against a gateway API key.
When to use this skill
- Scaffolding a new Next.js AI chatbot instead of hand-wiring
useChat, streaming, and markdown rendering from scratch - Adding a custom tool (server-executed or UI-answered) with a typed part
component that renders its
input-streaming/input-available/output-availablestates - Restricting or reordering the model list, or wiring web search per model
- Hardening the public
/api/chatroute (rate limiting, spend caps, auth) before putting it in front of real traffic - Understanding how assistant message "parts" (
text,tool-*,source-url) map to components so you can extend the chat UI safely
When not to use this skill
- The user needs persistent chat history, multi-user auth, or a database — this template has none of that; build it on top rather than expecting it out of the box
- The target stack isn't Next.js/React — this is a Next.js App Router
template tied to
useChatand RSC-style API routes - The goal is running an LLM entirely offline/bare-metal with no cloud
gateway → not this skill; see the
nightrunskill for a no-OS boot-to-LLM appliance instead - The ask is about the AI SDK or shadcn/ui in the abstract, unrelated to this specific starter template → use general AI SDK / shadcn/ui docs instead
Instructions
Step 1: Get the code
git clone --depth 1 https://github.com/shadcn-ui/chatbot-template.git
cd chatbot-template
Or click "Deploy with Vercel" on the README for a zero-config deploy — no env vars needed, since Vercel deployments authenticate to the AI Gateway via OIDC automatically and billing runs on the team's AI Gateway credits.
Step 2: Install and give the app a gateway credential
pnpm install
Then either pull an OIDC token from a linked Vercel project:
vercel link
vercel env pull
or create an API key in the Vercel dashboard (AI Gateway → API Keys) and set it locally:
cp .env.example .env.local
# then set AI_GATEWAY_API_KEY=... in .env.local
Step 3: Run the dev server
pnpm dev
Step 4: Configure the model list
Edit lib/models.ts — the first entry is the default model, and
isModelAllowed() restricts /api/chat to only the listed model IDs (see
Vercel AI Gateway models for valid IDs).
Step 5: Add a custom tool
- Create
tools/<name>.ts— the filename is the model-facing tool name. Export atool()with adescription, aninputSchema, and anexecutefunction; omitexecutefor tools the user answers in the UI (likeask_user). - Register it in
tools/index.ts(add it tobaseTools, or conditionally likeweb_search). - Add a part component in
components/parts/and a matchingcase "tool-<name>"incomponents/chat-message.tsx.
Message types are inferred from tool definitions via InferUITools, so
part.input/part.output are typed — renaming a tool field becomes a build
error instead of a silent undefined. See
references/commands.md for the full tool-part
table and file map.
Step 6: Add shadcn/ui components as needed
npx shadcn@latest add button
Step 7: Harden before public traffic
/api/chat is public and unauthenticated by default — every request
spends AI Gateway credits. Before real traffic:
- Rate limit it (Vercel Firewall/WAF, or
@upstash/ratelimit) to prevent a denial-of-wallet from a single client - Set an AI Gateway spend limit as a backstop
- Add auth if the chatbot isn't meant to be public
The route already validates the request body, restricts models to
lib/models.ts, caps output tokens/step count, and aborts generation on
client disconnect — those bound a single request, not overall volume.
Step 8: Verify before handing off
pnpm lint
pnpm typecheck
pnpm build
Best practices
- Treat
/api/chatas public by default — it has no auth or rate limiting out of the box; do not tell a user it's production-ready without step 7's hardening. - Register new tools in both places —
tools/index.tsand acase "tool-<name>"inchat-message.tsx. A tool with no part component renders nothing for its output. - Model order matters —
MODELS[0]inlib/models.tsis the default; don't assume alphabetical or arbitrary ordering is safe to change. - Use pnpm, not npm/yarn — the repo ships
pnpm-lock.yamlandpnpm-workspace.yaml; a different package manager will produce a divergent lockfile. - Prefer
npx shadcn@latest add <component>over hand-copying UI code — it keeps components in sync with the project'scomponents.jsonconfig. - Local dev needs a gateway credential; Vercel deploys don't — don't
add
AI_GATEWAY_API_KEYhandling for the Vercel-deployed path, OIDC already covers it.
References
- references/commands.md — curated command reference, key files, and tool-part extension map
- chatbot-template GitHub repository
- AI SDK docs
- shadcn/ui docs
- Vercel AI Gateway docs
- Project standards:
.agent-skills/skill-standardization/SKILL.md
Examples
Example 1: Scaffold and run locally
git clone --depth 1 https://github.com/shadcn-ui/chatbot-template.git
cd chatbot-template
pnpm install
cp .env.example .env.local
# set AI_GATEWAY_API_KEY=... in .env.local
pnpm dev
Example 2: Add a custom tool with a UI part
# 1. tools/weather.ts — export tool({ description, inputSchema, execute })
# 2. tools/index.ts — add weather: weatherTool to baseTools
# 3. components/parts/weather-part.tsx — render input-streaming/available/output states
# 4. components/chat-message.tsx — add case "tool-weather": <WeatherPart part={part} />
pnpm typecheck
pnpm dev