Install
$ agentstack add skill-jackspace-claudeskillz-ai-elements-chatbot ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
AI Elements Chatbot Components
Status: Production Ready Last Updated: 2025-11-07 Dependencies: tailwind-v4-shadcn (prerequisite), ai-sdk-ui (companion), nextjs (framework) Latest Versions: ai-elements@1.6.0, ai@5.0+, next@15+, react@19+
Quick Start (15 Minutes)
1. Verify Prerequisites
Before installing AI Elements, ensure these are already set up:
# Check Next.js version (needs 15+)
npx next --version
# Check AI SDK version (needs 5+)
npm list ai
# Check shadcn/ui is initialized
ls components/ui # Should exist with button.tsx etc
Why this matters:
- AI Elements is built ON TOP of shadcn/ui (won't work without it)
- Requires Next.js App Router (Pages Router not supported)
- AI SDK v5 has breaking changes from v4
Missing prerequisites? Use the tailwind-v4-shadcn skill first, then install AI SDK:
pnpm add ai@latest
2. Install AI Elements CLI
# Initialize AI Elements in your project
pnpm dlx ai-elements@latest init
# Add your first components
pnpm dlx ai-elements@latest add message conversation response prompt-input
CRITICAL:
- Components are copied into
components/ui/ai/(NOT installed as npm package) - Full source code ownership (modify as needed)
- Registry URL must be correct in
components.json
3. Create Basic Chat Interface
// app/chat/page.tsx
'use client';
import { useChat } from 'ai/react';
import { Conversation } from '@/components/ui/ai/conversation';
import { Message } from '@/components/ui/ai/message';
import { MessageContent } from '@/components/ui/ai/message-content';
import { Response } from '@/components/ui/ai/response';
import { PromptInput } from '@/components/ui/ai/prompt-input';
export default function ChatPage() {
const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat({
api: '/api/chat'
});
return (
{messages.map((msg) => (
))}
);
}
Done! You now have a working chat interface with:
- ✅ Streaming markdown rendering
- ✅ Auto-scrolling conversation
- ✅ Auto-resizing input
- ✅ Role-based message styling
The 5-Step Setup Process
Step 1: Install AI Elements CLI
pnpm dlx ai-elements@latest init
This:
- Creates
components/ui/ai/directory - Updates
components.jsonwith AI Elements registry - Adds necessary dependencies to package.json
Key Points:
- Run from project root (where package.json is)
- Requires shadcn/ui already initialized
- Will fail if
components.jsonmissing (runpnpm dlx shadcn@latest initfirst)
Step 2: Add Core Chat Components
# Essential components for basic chat
pnpm dlx ai-elements@latest add message message-content conversation response
# Optional: Input component
pnpm dlx ai-elements@latest add prompt-input actions suggestion
Component Purpose:
message: Container for single message (user/AI)message-content: Wrapper for message partsconversation: Auto-scrolling chat containerresponse: Markdown renderer (streaming-optimized)prompt-input: Auto-resizing textarea with toolbaractions: Copy/regenerate/edit buttonssuggestion: Quick prompt pills
Step 3: Add Advanced Components (Optional)
# For tool calling
pnpm dlx ai-elements@latest add tool
# For reasoning display (Claude/o1 style)
pnpm dlx ai-elements@latest add reasoning
# For source citations (Perplexity style)
pnpm dlx ai-elements@latest add sources inline-citation
# For code highlighting
pnpm dlx ai-elements@latest add code-block
# For conversation branching
pnpm dlx ai-elements@latest add branch
# For task lists
pnpm dlx ai-elements@latest add task
# For AI-generated images
pnpm dlx ai-elements@latest add image
# For web previews (Claude artifacts style)
pnpm dlx ai-elements@latest add web-preview
# For loading states
pnpm dlx ai-elements@latest add loader
When to add each:
tool: Building AI assistants with function callingreasoning: Showing AI's thinking process (like Claude or o1)sources: Adding citations and references (like Perplexity)code-block: Chat includes code snippetsbranch: Multi-turn conversations with variationstask: AI generates task lists with file referencesimage: AI generates images (DALL-E, Stable Diffusion)web-preview: AI generates HTML/websites (Claude artifacts)loader: Show loading states during streaming
Step 4: Create API Route
Create /app/api/chat/route.ts:
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: openai('gpt-4o'),
messages,
});
return result.toDataStreamResponse();
}
Key Points:
- Must use AI SDK v5
streamText()(not v4OpenAIStream()) - Returns
toDataStreamResponse()for streaming - Client auto-receives updates via
useChat()hook
Step 5: Verify Installation
# Check components installed
ls components/ui/ai/
# Expected output:
# message.tsx, message-content.tsx, conversation.tsx, response.tsx, prompt-input.tsx, ...
# Start dev server
pnpm dev
# Test chat interface at http://localhost:3000/chat
Verification Checklist:
- [ ] All components in
components/ui/ai/ - [ ]
components.jsonhas AI Elements registry - [ ] No TypeScript errors
- [ ] Chat interface renders
- [ ] Streaming works (type message → get response)
- [ ] Auto-scroll works during streaming
Critical Rules
Always Do
✅ Initialize shadcn/ui BEFORE AI Elements - AI Elements requires shadcn/ui as foundation ✅ Use AI SDK v5 - v4 is incompatible (breaking changes) ✅ Use Next.js App Router - Pages Router not supported ✅ Wrap with 'use client' - All AI Elements components are client-side ✅ Pass raw markdown to Response component - Not pre-rendered HTML ✅ Use Conversation component as container - Handles auto-scroll and virtualization ✅ Conditionally show voice input - Only works in Chrome/Edge (not Firefox/Safari) ✅ Merge consecutive reasoning blocks - Prevent duplication in long responses
Never Do
❌ Install AI Elements as npm package - It's a CLI tool that copies components ❌ Use with AI SDK v4 - Will fail with type errors and data format issues ❌ Forget 'use client' directive - Components use React hooks (client-only) ❌ Mix with other component libraries - Built for shadcn/ui only (Tailwind classes) ❌ Manually write component code - Use CLI to ensure correct patterns ❌ Skip prerequisites check - Will fail silently with confusing errors ❌ Use in Pages Router - Requires App Router features ❌ Assume voice input works everywhere - Web Speech API is Chrome/Edge only
Known Issues Prevention
This skill prevents 8 documented issues:
Issue #1: PromptInputSpeechButton Not Working (Firefox/Safari)
Error: Voice input button doesn't respond or throws SpeechRecognition is not defined Source: https://github.com/vercel/ai-elements/issues/210 Why It Happens: Web Speech API only supported in Chromium browsers (Chrome, Edge) Prevention:
// Conditionally show voice button
const isSpeechSupported = typeof window !== 'undefined' &&
('webkitSpeechRecognition' in window || 'SpeechRecognition' in window);
Issue #2: PromptInput Not Responsive on Mobile
Error: Input overflows or doesn't resize properly on small screens Source: https://github.com/vercel/ai-elements/issues/153 Why It Happens: Missing responsive min-height constraints Prevention:
Issue #3: Multiple Thinking Elements in Long Responses
Error: Duplicate reasoning/thinking blocks appear instead of single merged block Source: https://github.com/vercel/ai-elements/issues/106 Why It Happens: Streaming creates separate components for each chunk Prevention:
// Merge reasoning chunks client-side
const processedMessages = messages.map(msg => {
if (msg.annotations?.reasoning) {
// Combine all reasoning into single string
const merged = Array.isArray(msg.annotations.reasoning)
? msg.annotations.reasoning.join('\n\n')
: msg.annotations.reasoning;
return { ...msg, annotations: { ...msg.annotations, reasoning: merged } };
}
return msg;
});
Issue #4: Component Not Found After Installation
Error: Cannot find module '@/components/ui/ai/message' Source: Common user error Why It Happens: AI Elements not initialized or wrong registry URL Prevention:
# Verify components.json has correct registry
cat components.json | grep -A5 "ai-elements"
# Re-initialize if missing
pnpm dlx ai-elements@latest init
# Check components directory exists
ls components/ui/ai/
Issue #5: AI SDK v5 Breaking Changes
Error: Type errors, undefined properties, or streaming not working Source: https://sdk.vercel.ai/docs/ai-sdk-core/migration Why It Happens: v5 has breaking API changes from v4 Prevention:
// ✅ v5 (correct)
const { messages } = useChat(); // Direct messages array
msg.toolInvocations // Tool calls here
// ❌ v4 (incorrect)
const { data } = useChat(); // Wrapped in data object
msg.tool_calls // Different property name
Issue #6: Maximum Update Depth Exceeded
Error: React error "Maximum update depth exceeded" during streaming Source: https://github.com/vercel/ai-elements/issues/97 Why It Happens: Infinite re-render loop from unstable callbacks Prevention:
// Memoize callbacks to prevent re-renders
import { useCallback } from 'react';
const { messages } = useChat({
api: '/api/chat',
onFinish: useCallback((message) => {
console.log('Finished', message);
}, []) // Stable dependency array
});
Issue #7: Copy Button Returns HTML Instead of Markdown
Error: Copying message pastes HTML instead of plain markdown Source: https://github.com/vercel/ai-elements/issues/180 Why It Happens: Actions.Copy uses innerHTML by default Prevention:
// Pass raw markdown content, not rendered HTML
Issue #8: Tailwind v4 CSS Variable Issues
Error: Components have no styling or broken colors Source: Common with Tailwind v4 migration Why It Happens: Missing CSS variables or wrong @theme configuration Prevention:
# Use tailwind-v4-shadcn skill to fix, or manually verify:
# Check src/index.css has:
@import "tailwindcss";
:root {
--background: hsl(0 0% 100%);
--foreground: hsl(0 0% 3.9%);
/* ... other variables */
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
}
Configuration Files Reference
components.json (AI Elements Registry)
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/index.css",
"baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {
"shadcn": "https://ui.shadcn.com/registry",
"ai-elements": "https://www.shadcn.io/ai/registry"
}
}
Why these settings:
"rsc": false- AI Elements are client components (not RSC compatible)"tsx": true- TypeScript required for type safety"tailwind.config": ""- Tailwind v4 doesn't use config fileregistries- Both shadcn and AI Elements registries needed
Common Patterns
Pattern 1: Basic Chat with Actions
'use client';
import { useChat } from 'ai/react';
import { Conversation, Message, MessageContent, Response, Actions } from '@/components/ui/ai';
import { PromptInput } from '@/components/ui/ai/prompt-input';
export default function ChatWithActions() {
const { messages, input, handleInputChange, handleSubmit, reload, stop } = useChat();
return (
{messages.map((msg) => (
{msg.role === 'assistant' && (
reload()} />
)}
))}
);
}
When to use: Every chat interface (copy and regenerate are essential UX)
Pattern 2: Chat with Tool Calling
'use client';
import { useChat } from 'ai/react';
import { Tool } from '@/components/ui/ai/tool';
import { z } from 'zod';
export default function ChatWithTools() {
const { messages } = useChat({
api: '/api/chat',
async onToolCall({ toolCall }) {
if (toolCall.toolName === 'get_weather') {
// Execute tool
return { temperature: 72, conditions: 'Sunny' };
}
}
});
return (
{messages.map((msg) => (
{msg.content && }
{/* Render tool invocations */}
{msg.toolInvocations?.map((tool) => (
))}
))}
);
}
When to use: AI assistants with function calling (like ChatGPT with plugins)
Pattern 3: Chat with Reasoning Display
'use client';
import { useChat } from 'ai/react';
import { Reasoning } from '@/components/ui/ai/reasoning';
export default function ChatWithReasoning() {
const { messages, isLoading } = useChat({
api: '/api/chat',
streamProtocol: 'text'
});
return (
{messages.map((msg, idx) => {
const reasoning = msg.annotations?.reasoning;
const isStreaming = isLoading && idx === messages.length - 1;
return (
{reasoning && (
)}
);
})}
);
}
When to use: Claude-style thinking, o1-style reasoning, chain-of-thought prompting
Pattern 4: Chat with Source Citations
'use client';
import { useChat } from 'ai/react';
import { Sources, InlineCitation } from '@/components/ui/ai';
export default function ChatWithSources() {
const { messages } = useChat({
api: '/api/chat'
});
return (
{messages.map((msg) => {
const sources = msg.annotations?.sources || [];
return (
{/* Show sources at bottom */}
{sources.length > 0 && (
)}
);
})}
);
}
When to use: RAG applications, Perplexity-style search, citation-backed responses
Pattern 5: Chat with Code Blocks
'use client';
import { useChat } from 'ai/react';
import { CodeBlock } from '@/components/ui/ai/code-block';
import { Response } from '@/components/ui/ai/response';
export default function ChatWithCode() {
const { messages } = useChat();
return (
{messages.map((msg) => (
{/* Response component auto-renders code blocks */}
(
)
}}
/>
))}
);
}
When to use: Coding assistants, technical documentation chat, code review
Using Bundled Resources
Scripts (scripts/)
setup-ai-elements.sh - Complete initialization script
#!/bin/bash
# Automated AI Elements setup
# Check prerequisites
echo "Checking prerequisites..."
# Check Next.js
if ! command -v next &> /dev/null; then
echo "❌ Next.js not found. Install: pnpm add next"
exit 1
fi
# Check shadcn/ui
if [ ! -f "components.json" ]; then
echo "❌ shadcn/ui not initialized. Run: pnpm dlx shadcn@latest init"
exit 1
fi
# Check AI SDK
if ! grep -q '"ai"' package.json; then
echo "Installing AI SDK
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [jackspace](https://github.com/jackspace)
- **Source:** [jackspace/ClaudeSkillz](https://github.com/jackspace/ClaudeSkillz)
- **License:** MIT
- **Homepage:** http://claudeskillz.jackspace.com/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.