-
Get your own AI_GATEWAY_API_KEY in Vercel.https://vercel.com/
-
Create a
.env.localfile in the root of the project with the following content:
AI_GATEWAY_API_KEY=your_api_key_here
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun devOpen http://localhost:3000 with your browser to see the result.
- What is the weather in San Francisco?
- What is the best airfryer?
- Show me AAPL stocks.
gen-ui-app/
├── ai/
│ └── tools.ts # AI tool definitions (weather, stock, ecommerce)
├── app/
│ ├── api/
│ │ └── chat/
│ │ └── route.ts # API endpoint that handles chat requests and streams AI responses
│ ├── globals.css # Global styles
│ ├── layout.tsx # Root layout component
│ └── page.tsx # Main chat interface with useChat hook
├── components/
│ ├── ECommerce.tsx # Product card grid component for airfryer recommendations
│ ├── Stock.tsx # Stock price display component with price/change info
│ └── Weather.tsx # Weather card component showing temperature/humidity/wind
└── public/
└── images/ # Product images for ecommerce display
To add a new generative UI component:
-
Create the tool in
ai/tools.ts:export const myTool = tool({ description: 'Description of when to use this tool', inputSchema: jsonSchema<{ param: string }>({ type: 'object', properties: { param: { type: 'string', description: 'Parameter description' }, }, required: ['param'], }), execute: async ({ param }) => { // Return data for your component return { param, result: 'data' }; }, }); // Add to the tools export export const tools = { // ...existing tools displayMyTool: myTool, };
-
Create the component in
components/MyComponent.tsx:type MyComponentProps = { param: string; result: string; }; export function MyComponent({ param, result }: MyComponentProps) { return <div>{/* Your UI here */}</div>; }
-
Add rendering logic in
app/page.tsx:import { MyComponent } from '@/components/MyComponent'; // Inside the message.parts.map(), add: if (part.type === 'tool-displayMyTool') { switch (part.state) { case 'input-available': return <div key={index}>Loading...</div>; case 'output-available': return <MyComponent key={index} {...(part.output as MyComponentProps)} />; case 'output-error': return <div key={index}>Error: {part.errorText}</div>; } }
-
Update the system prompt in
app/api/chat/route.tsto tell the AI when to use your new tool.