Chapter 10: Next.js AI Frontends [chapter] deterministic
## Introduction Developing an AI-powered front-end with Next.js brings together the best of server-side rendering, API routes, and modern React patterns. In this chapter, we’ll cover how to integrate
Introduction Developing an AI-powered front-end with Next.js brings together the best of server-side rendering, API routes, and modern React patterns. In this chapter, we’ll cover how to integrate AI models, stream responses, and build responsive interfaces that delight users. By the end of the chapter, you’ll be able to create a fully functional AI chat interface that leverages real-time streaming and handles edge cases gracefully.
Setting Up the Project
Before diving into the code, let’s set up a Next.js project. Use the create-next-app CLI to scaffold a new project:
```bash npx create-next-app@latest my-ai-app
`
Once the project is created, navigate to the directory and install the required dependencies:
```bash cd my-ai-app npm install @ai-sdk/openai openai
`
We’ll also need a .env.local file to store our OpenAI API key:
```plaintext OPENAI_API_KEY=sk-...
`
Building the AI Chat UI
Server-Side Rendering
Next.js supports server-side rendering (SSR) out of the box. We’ll use this to render the initial page with a placeholder UI for the chat interface. Create a new file app/page.tsx:
```tsx 'use client'; import { useState } from 'react'; export default function HomePage() { const [messages, setMessages] = useState([]); return (
AI Chat
{messages.map((msg, idx) => (
{msg.role === '' ? 'You' : 'AI'}: {msg.content}
))}
setInput(e.target.value)} placeholder="Ask me anything..." className="w-full p-2 border rounded" />
Send
); }
`
Handling User Input
In the above code, we’ve added a simple form that captures input. We’ll define the handleSubmit function to send the message to an AI endpoint.
Streaming AI Responses
Streaming with Next.js
To stream responses from an AI model, we need an API route that streams the generated content. Create a new file app/api/chat/route.ts:
```ts import { openai } from '@ai-sdk/openai'; import { streamText } from 'ai'; import { NextRequest, NextResponse } from 'next/server'; export async function POST(req: NextRequest) { const { messages } = await req.json(); const result = await streamText({ model: openai('gpt-4'), : 'You are a helpful AI .', messages, }); return new Response(result.toTextStreamResponse()); }
`
This route uses the streamText function from the ai SDK to stream the AI’s response. The response is sent as a text stream, which the client can consume in real-time.
Consuming the Stream on the Client
Now, let’s update the client to handle the streaming response. Modify the handleSubmit function:
```tsx const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!input.trim()) return; const newMessages = [...messages, { role: '', content: input }]; setMessages(newMessages); setInput(''); const response = await fetch('/api/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ messages: newMessages }), }); const reader = response.body?.getReader(); const decoder = new TextDecoder(); let aiContent = ''; while (true) { const { done, value } = await reader!.read(); if (done) break; aiContent += decoder.decode(value); setMessages([...newMessages, { role: '', content: aiContent }]); } };
`
This code reads the streamed response chunk by chunk, updates the UI in real-time, and maintains a smooth experience.
Building Responsive AI Interfaces
Responsive Design with Tailwind CSS Next.js integrates seamlessly with Tailwind CSS for responsive design. Install Tailwind:
```bash npm install tailwindcss postcss autoprefixer npx tailwindcss init -p
`
Configure tailwind.config.js to scan your files:
```js module.exports = { content: ['./app/**/*.{js,ts,jsx,tsx}'], theme: { extend: {} }, plugins: [], };
`
Now, you can use Tailwind classes to ensure the chat interface works well on all devices. For example, adjust the padding and font sizes for smaller screens:
```tsx
...
`
Enhancing the UI with Animations
To make the interface feel more dynamic, add simple animations. Use CSS transitions or libraries like framer-motion:
```bash npm install framer-motion
`
Animate the message bubbles:
```tsx import { AnimatePresence, motion } from 'framer-motion'; // Inside the message loop
{msg.role === '' ? 'You' : 'AI'}: {msg.content}
`
Testing and Debugging
REPL Environment
When developing AI prompts, it’s useful to have a REPL environment to test different prompts quickly. Use the REPL concept from the glossary to experiment with prompt templates. For example, in the terminal:
```bash node -e "console.log('Hello, AI!');"
`
Or use a dedicated REPL tool like node-repl to iterate on prompts without restarting the server.
Using the CLASSIFIER_SYSTEM_PROMPT
If you’re building a classifier as part of your AI workflow, define a CLASSIFIER_SYSTEM_PROMPT that guides the model in categorizing content. For instance:
ts
const classifierPrompt = You are a classifier. Given the following text, categorize it into one of the following categories: [Tech, Business, Health]. Respond with only the category name.`;
`
Integrate this prompt into your AI pipeline to classify queries before routing them to the appropriate model or handler.