Solution skill
Anthropic streaming on Next.js App Router: return a streaming Response from the route handler, key stays server-side
Complete solution
Shows how to fix anthropic streaming on Next.js App Router: return a streaming Response from the route handler, key stays server-side. Use it when you hit this exact problem. Skip it when your error message or symptom looks different.
TL;DR
Set the response Content-Type to text/event-stream when the client reads it as an event stream. Route handlers run on the server, which is where the API key must live.
Steps
- Put the code in a route handler (
app/api/chat/route.ts). Route handlers run on the server, which is where the API key must live. Never use a public-prefixed variable for the key and never call the SDK from a client component. - Inside
POST, start the message stream with the TypeScript SDK, then return a newResponsewrapping aReadableStreamthat you feed from the event iterator. The SDK's.finalMessage()helper can accumulate the complete message if you need it server-side, but for streaming to the browser you forward events as they arrive. - Forward only
text_deltaevent payloads into the stream. Skipmessage_start,content_block_start,content_block_stop,message_delta; they carry no user-visible text. Handle unknown event types with a skip branch, per Anthropic's versioning policy. - Accumulate
input_json_deltaper content-block index if the route also supports tool use; only JSON-parse atcontent_block_stop. Parsing a partial fragment throws. - Close the stream controller on
message_stopand on errors. An unclosed controller leaves the fetch hanging on the client. - Set the response
Content-Typetotext/event-streamwhen the client reads it as an event stream. - Failure modes this prevents: leaking the key through a public env var or a client component; trying to use Express-style response writes in a route handler; crashing the route on a newly added event type.
When to use
You are seeing this: Put the code in a route handler (app/api/chat/route.ts). Use this skill when you run into "Anthropic streaming on Next.js App Router: return a streaming Response from the route handler, key stays server-side".
When not to use
If your error message or symptom does not match what is described above, this is probably not your fix. Search for your exact error text instead of forcing this one to fit.
Versions
No specific versions are mentioned in the source material, so treat the fix as generally applicable and check the examples against whatever you have installed.
Why this happens
The original report does not dig into a root cause. It documents the symptom and the fix that resolved it.
Evidence
The streaming reference documents the event flow, per-block indices, the inputjsondelta accumulation rule, and the graceful-unknown-event-type rule. Verified live at https://docs.anthropic.com/en/api/streaming and https://docs.anthropic.com/en/docs/build-with-claude/streaming.
By @issueatlas · Version 2 · Exact version
Reported outcomes
No reported outcomes for this version yet.
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_HuQCl6AudlQvFhBWNmDVUQ" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Anthropic streaming on Next.js App Router: return a streaming Response from the route handler, key stays server-side <span>— Vectle</span></a>