AI SDK con Next.js
El Vercel AI SDK está diseñado para funcionar perfectamente con Next.js, soportando tanto el App Router como el Pages Router. Esta guía se centra en el App Router con Route Handlers y Server Actions.
Opciones de integración con Next.js
- Route Handlers: Rutas API en el directorio app/api/
- Server Actions: Funciones del servidor llamadas desde componentes
- Server Components: Generar contenido de IA durante SSR
- Middleware: Procesamiento de requests con IA
Configuración del proyecto
Para comenzar, crea una aplicación Next.js con TypeScript y Tailwind, instala el AI SDK y configura tu clave API como variable de entorno.
# Create Next.js app
npx create-next-app@latest my-ai-app --typescript --tailwind --app
# Install AI SDK
cd my-ai-app
npm install ai @ai-sdk/openai
# Add environment variable
echo "OPENAI_API_KEY=your-key" > .env.local
Enfoque con Route Handlers
Los Route Handlers son rutas API definidas en el directorio app/api/. Son el enfoque más común para interfaces de chat ya que soportan streaming nativo y se integran fácilmente con useChat.
Crear ruta API
// app/api/chat/route.ts
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';
// Allow streaming responses up to 30 seconds
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: openai('gpt-4-turbo'),
system: 'You are a helpful assistant.',
messages,
});
return result.toDataStreamResponse();
}
Componente cliente
El componente cliente usa el hook useChat para conectar con la ruta API y renderizar la interfaz de chat con streaming automático.
// app/chat/page.tsx
'use client';
import { useChat } from 'ai/react';
export default function ChatPage() {
const { messages, input, handleInputChange, handleSubmit } = useChat();
return (
<div className="max-w-2xl mx-auto p-4">
<h1 className="text-2xl font-bold mb-4">AI Chat</h1>
<div className="space-y-4 mb-4">
{messages.map((m) => (
<div key={m.id} className="p-4 rounded-lg bg-gray-100">
<strong>{m.role}:</strong> {m.content}
</div>
))}
</div>
<form onSubmit={handleSubmit} className="flex gap-2">
<input
value={input}
onChange={handleInputChange}
className="flex-1 p-2 border rounded"
placeholder="Ask something..."
/>
<button className="px-4 py-2 bg-black text-white rounded">
Send
</button>
</form>
</div>
);
}
Enfoque con Server Actions
Las Server Actions permiten llamar funciones del servidor directamente desde componentes de React. Son ideales para operaciones únicas de IA como generación de texto o datos estructurados.
// app/actions.ts
'use server';
import { openai } from '@ai-sdk/openai';
import { generateText, streamText } from 'ai';
import { createStreamableValue } from 'ai/rsc';
// Non-streaming action
export async function generateResponse(prompt: string) {
const { text } = await generateText({
model: openai('gpt-4-turbo'),
prompt,
});
return text;
}
// Streaming action
export async function streamResponse(prompt: string) {
const stream = createStreamableValue('');
(async () => {
const result = streamText({
model: openai('gpt-4-turbo'),
prompt,
});
for await (const delta of result.textStream) {
stream.update(delta);
}
stream.done();
})();
return stream.value;
}
Usar Server Actions
Desde un componente cliente, puedes importar y llamar las Server Actions directamente. El streaming se consume con readStreamableValue para mostrar respuestas progresivas.
// app/generate/page.tsx
'use client';
import { useState } from 'react';
import { useStreamableValue } from 'ai/rsc';
import { streamResponse } from '../actions';
export default function GeneratePage() {
const [response, setResponse] = useState('');
const [streamedValue, setStreamedValue] = useState('');
const handleGenerate = async () => {
const stream = await streamResponse('Write a haiku about coding');
for await (const value of readStreamableValue(stream)) {
setStreamedValue(value || '');
}
};
return (
<div className="p-4">
<button onClick={handleGenerate}>Generate Haiku</button>
<p>{streamedValue}</p>
</div>
);
}
Datos estructurados con Server Actions
Con generateObject y un esquema Zod, puedes obtener objetos tipados directamente del modelo. Esto garantiza que la respuesta de la IA cumpla una estructura específica.
// app/actions.ts
'use server';
import { openai } from '@ai-sdk/openai';
import { generateObject } from 'ai';
import { z } from 'zod';
const RecipeSchema = z.object({
name: z.string(),
ingredients: z.array(z.string()),
steps: z.array(z.string()),
prepTime: z.number(),
cookTime: z.number(),
});
export async function generateRecipe(dish: string) {
const { object } = await generateObject({
model: openai('gpt-4-turbo'),
schema: RecipeSchema,
prompt: `Generate a recipe for ${dish}`,
});
return object;
}
Runtime Edge
El runtime Edge ofrece arranques más rápidos y menor latencia global. Es ideal para rutas de IA que necesitan responder rápidamente desde cualquier región.
// app/api/chat/route.ts
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';
// Use Edge runtime for faster cold starts
export const runtime = 'edge';
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: openai('gpt-4-turbo'),
messages,
});
return result.toDataStreamResponse();
}
Integración con middleware
El middleware de Next.js permite interceptar solicitudes antes de que lleguen a la ruta API. Es útil para autenticación, rate limiting u otras validaciones de seguridad.
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
// Add rate limiting, auth checks, etc.
const apiKey = request.headers.get('x-api-key');
if (request.nextUrl.pathname.startsWith('/api/chat')) {
if (!apiKey) {
return NextResponse.json(
{ error: 'API key required' },
{ status: 401 }
);
}
}
return NextResponse.next();
}
export const config = {
matcher: '/api/:path*',
};
Variables de entorno
Las claves API deben almacenarse en .env.local y nunca exponerse al cliente. El AI SDK lee automáticamente las variables con nombres estándar como OPENAI_API_KEY.
# .env.local
OPENAI_API_KEY=sk-...
# For multiple providers
ANTHROPIC_API_KEY=sk-ant-...
GOOGLE_GENERATIVE_AI_API_KEY=...
Consideraciones de despliegue
Al desplegar en Vercel, configura maxDuration según tu plan:
Hobby (10s), Pro (60s), Enterprise (900s). Para tareas largas,
considera usar trabajos en background o colas.
💡 Puntos clave
- • Route Handlers son ideales para interfaces de chat en streaming
- • Server Actions funcionan bien para operaciones únicas de IA
- • Usa Edge runtime para mejores tiempos de arranque globales
- • Configura
maxDurationsegún tu despliegue - • Mantén las claves API solo en el servidor
📚 Más recursos
-
Guía de Next.js App Router →
Guía oficial para integrar con Next.js App Router.
-
AI SDK RSC →
Guía de integración con React Server Components.