Vercel AI SDK and Frontend Integration
On this page
Updated November 3, 2026 based on AI SDK 7 documentation (
ai7.0.x,@ai-sdk/react4.x):useChatworks withDefaultChatTransportandsendMessage, messages display viaparts, the route returnscreateUIMessageStreamResponse,systembecomesinstructions, and the@ai-sdk/xai5 provider no longer supports Chat Completions:xai()uses the Responses API (code verified with TypeScript compiler usingai7.0.162 and@ai-sdk/xai5.0.38). The previous version used the AI SDK 4 API (input,handleSubmit,isLoading,toDataStreamResponse). Sources: AI SDK, Chatbot · AI SDK, xAI provider.
The Vercel AI SDK for Web Applications
The Vercel AI SDK is a TypeScript framework designed to integrate AI models into web applications. It provides React hooks, streaming utilities, and a unified abstraction that natively supports xAI/Grok via the @ai-sdk/xai package.
If you’re building a Next.js, Nuxt, SvelteKit, or any React application that needs to display streaming responses, the Vercel AI SDK simplifies the work significantly.
Installation
Install the core SDK and the xAI provider:
npm install ai @ai-sdk/xai
Configure your API key in the environment variables:
# .env.local
XAI_API_KEY=your-api-key
Server Side: Generating Text
The generateText function is the simplest equivalent of client.chat.create(). One thing has changed, and it concerns this course directly: since version 5 of the @ai-sdk/xai provider (September 2026), compatible with AI SDK 7, the provider no longer supports the Chat Completions endpoint. xai(model) uses the Responses API, which xAI now recommends. The xai.chat(model) method, which some migration guides still cite, existed only in provider version 4; for code that must stay on Chat Completions, use the OpenAI SDK pointed at xAI instead (Lesson 5).
import { generateText } from "ai";
import { xai } from "@ai-sdk/xai";
const { text } = await generateText({
model: xai("grok-4.7"), // xAI Responses API
instructions: "You are a technical assistant.",
prompt: "Explain the concept of containerization.",
});
console.log(text);
The xai provider automatically reads XAI_API_KEY from the environment; createXai() lets you create an instance with custom settings. The instructions option replaces system, which is still accepted but deprecated in AI SDK 7.
Server-Side Streaming
For streaming, use streamText. The response reads chunk by chunk from textStream:
import { streamText } from "ai";
import { xai } from "@ai-sdk/xai";
const result = streamText({
model: xai("grok-4.7"),
instructions: "You are a teaching assistant.",
messages: [
{ role: "user", content: "How does a relational database work?" },
],
});
for await (const chunk of result.textStream) {
process.stdout.write(chunk);
}
Client Side: The useChat Hook
The useChat hook is the centerpiece on the frontend. It handles conversation history, streaming, and request state; the input field, however, remains a simple React state that you manage:
"use client";
import { useChat } from "@ai-sdk/react";
import { DefaultChatTransport } from "ai";
import { useState } from "react";
export default function ChatPage() {
const { messages, sendMessage, status } = useChat({
transport: new DefaultChatTransport({ api: "/api/chat" }),
});
const [input, setInput] = useState("");
return (
<div>
{messages.map((m) => (
<div key={m.id}>
<strong>{m.role === "user" ? "You" : "Grok"}</strong>
{m.parts.map((part, i) =>
part.type === "text" ? <p key={i}>{part.text}</p> : null
)}
</div>
))}
<form
onSubmit={(e) => {
e.preventDefault();
if (input.trim()) {
sendMessage({ text: input });
setInput("");
}
}}
>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Ask your question..."
disabled={status !== "ready"}
/>
<button type="submit" disabled={status !== "ready"}>
Send
</button>
</form>
</div>
);
}
What useChat Handles Automatically
- Message history: Accumulates exchanges; each message carries
parts(text, tool calls…), display these rather than the oldcontentfield - Streaming: Displays the response as it generates
- Request state:
statusisreadywhen a new message can be sent - Error handling: Intercepts network and API errors
- Cancellation:
stop()interrupts an ongoing generation
Corresponding API Route
The hook expects a route that returns a stream of UI messages. Here is the implementation with the Next.js App Router, modeled after the official AI SDK 7 example:
// app/api/chat/route.ts
import {
convertToModelMessages,
createUIMessageStreamResponse,
streamText,
toUIMessageStream,
type UIMessage,
} from "ai";
import { xai } from "@ai-sdk/xai";
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();
const result = streamText({
model: xai("grok-4.7"),
instructions: "You are a helpful assistant. Respond in English.",
messages: await convertToModelMessages(messages),
});
return createUIMessageStreamResponse({
stream: toUIMessageStream({ stream: result.stream }),
});
}
Two conversions wrap the exchange: convertToModelMessages transforms UI messages received from the client into model messages, and toUIMessageStream does the reverse on the response stream. The toUIMessageStreamResponse() methods on the streamText result still work in AI SDK 7, but they are deprecated; as for the old toDataStreamResponse(), it no longer exists.
Key Takeaways
- The Vercel AI SDK supports xAI/Grok via the
@ai-sdk/xaipackage generateTextfor synchronous responses,streamTextfor streaming- The
useChathook manages the complete state of a conversation on the client createUIMessageStreamResponseandtoUIMessageStreamreturn the stream expected byuseChat;toDataStreamResponse()no longer exists- Since
@ai-sdk/xai5, the provider no longer supports Chat Completions:xai()uses the Responses API; to stay on Chat Completions, use the OpenAI SDK - The
createXai()provider automatically detects the API key in the environment