Hi Team
Problem Summary
I have a Next.js 15 app using AI SDK v5 with OpenRouter that shows streaming responses working perfectly on the server side (console shows all text-delta parts), but the UI displays the complete response all at once instead of streaming word-by-word.
Tech Stack
- AI SDK: v5 (latest)
- Next.js: 15
- Provider: OpenRouter (Claude Sonnet 4, GPT-4o, etc.)
- Streaming: Server-Sent Events with resumable streams
- UI: React with
useChathook
Server-Side Evidence (Working)
🔥 STREAM PART: {"type":"text-delta","id":"gen-xxx","delta":"Hi "}
🔥 STREAM PART: {"type":"text-delta","id":"gen-xxx","delta":"there, "}
🔥 STREAM PART: {"type":"text-delta","id":"gen-xxx","delta":"Driss! "}
// ... continues streaming properly
Client-Side Issue
- UI shows complete response instantly instead of streaming
useChatwithexperimental_throttle: 100- Using
JsonToSseTransformStream()in response - Resumable stream context with Redis
Key Code Snippets
API Route:
const stream = createUIMessageStream({
execute: ({ writer: dataStream }) => {
const result = streamText({
model: userProvider.languageModel(selectedChatModel),
experimental_transform: smoothStream({ chunking: 'word' }),
// ... other config
});
result.consumeStream();
dataStream.merge(result.toUIMessageStream({ sendReasoning: true }));
}
});
return new Response(
streamContext
? await streamContext.resumableStream(streamId, () =>
stream.pipeThrough(new JsonToSseTransformStream())
)
: stream.pipeThrough(new JsonToSseTransformStream())
);
Client:
const { messages, status } = useChat<UIMessage>({
experimental_throttle: 100,
transport: new DefaultChatTransport({
api: '/api/chat',
fetch: fetchWithErrorHandlers,
}),
onData: (dataPart) => setDataStream(ds => [...ds, dataPart])
});
What I’ve Tried
Verified JsonToSseTransformStream()is used
Server logs show proper streaming parts
smoothStream({ chunking: 'word' })configured
experimental_throttle: 100set
UI still shows complete response at once
Has anyone encountered similar issues where server-side streaming works but client-side doesn’t update incrementally?
Thanks