Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
chatbot-template

chatbot-template

> 前端框架
Free

A minimal chatbot template built with Next.js, AI SDK, shadcn/ui, shadcn/react, shadcn/typeset. It r

929 stars0 likes1 views
GitHub

About

A minimal chatbot template built with Next.js, AI SDK, shadcn/ui, shadcn/react, shadcn/typeset. It r

chatbot-template

A minimal chatbot template built with Next.js, the AI SDK, shadcn/ui, shadcn/react, shadcn/typeset and the Vercel AI Gateway.

Features

  • Streaming chat with markdown rendering and shadcn/typeset
  • Tool calling example
  • Web search via each provider's built-in search tool
  • Human-in-the-loop questionnaire. The model can ask clarifying questions, answered with the shadcn questionnaire component

Deploy

That's it — no configuration needed. Vercel deployments authenticate to the AI Gateway automatically via OIDC, and usage runs on your team's AI Gateway credits.

Local development

bash
pnpm install

Then give the app a gateway credential, either by pulling an OIDC token from your linked Vercel project:

bash
vercel link
vercel env pull

or by creating an API key in the Vercel dashboard (AI Gateway → API Keys) and adding it to .env.local:

bash
cp .env.example .env.local
# then set AI_GATEWAY_API_KEY=...

Start the dev server:

bash
pnpm dev

Configuration

Env var Required Description
AI_GATEWAY_API_KEY Local dev only AI Gateway API key. Not needed on Vercel deployments (OIDC).

The model list lives in lib/models.ts — the first entry is the default model.

Security

The /api/chat route is public and unauthenticated — every request spends your AI Gateway credits. That's fine for a personal demo, but before putting it in front of real traffic you should:

  • Rate limit it. Add Vercel Firewall / WAF rules or @upstash/ratelimit so a single client can't drain your credits (denial-of-wallet).
  • Cap spend. 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 and step count, and aborts generation on client disconnect — but those bound a single request, not overall volume.

How it works

  • app/api/chat/route.ts streams responses with streamText
  • components/chat.tsx renders the conversation with useChat and shadcn chat primitives.
  • tools/ defines the tools — one file per tool (the filename is the model-facing tool name), composed in tools/index.ts: a server-executed GitHub repo lookup, the interactive ask_user questionnaire, and provider-native web search.

Tool parts

Assistant messages are a list of typed parts. components/chat-message.tsx switches on part.type and delegates each one to a component in components/parts/:

Part type Component Renders
text text-part.tsx Markdown via react-markdown and shadcn/typeset.
tool-github_repo github-repo-part.tsx A spinner while the lookup runs, then a linked stat line (stars, forks, language).
tool-web_search web-search-part.tsx A "Searching the web…" status while the search runs, then a persistent "Searched the web" line per search.
tool-ask_user ask-user-part.tsx The answered questions inline. Pending questions render in question-card.tsx, pinned to the scroller bottom.
source-url sources-part.tsx Web search citations, deduped into a "Searched N websites" drawer once the message finishes streaming.

Tool parts move through states as the stream progresses — input-streaming → input-available → output-available (or output-error) — and each component switches on part.state to show progress, results, and failures.

Adding your own tool

  1. Create tools/.ts (the filename is the model-facing tool name) exporting a tool() with a description, an inputSchema, and an execute function (omit execute for tools the user answers in the UI, like ask_user), then register it in tools/index.ts.
  2. Add a part component in components/parts/ and a case "tool-" in chat-message.tsx.

Message types are inferred from the tool definitions via InferUITools, so part.input and part.output are fully typed in your part component — renaming a tool field is a build error, not a silent undefined.

Adding components

bash
npx shadcn@latest add button

License

MIT — see LICENSE.

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

开发者工具

No comments yet. Be the first to share.

> Details

PublishedSep 9, 2026
UpdatedSep 17, 2026
Category前端框架
PricingFree

> Related tools

R
React
用于构建用户界面的 JavaScript 库
V
Vue.js
渐进式 JavaScript 框架
N
Next.js
基于 React 的全栈 Web 框架