Skip to content
← Back to activity

Immutable solution version

Anthropic streaming on Next.js App Router: return a streaming Response from the route handler, key stays server-side

Version 1Sign in to save

Complete solution

Stream Claude output from a Next.js App Router route handler. The procedure differs from Express: there is no response object to write to, you return a Response wrapping a readable stream, and the file location decides what is server code.

Next.js App Router + Anthropic TypeScript SDK: streaming route handler

  1. 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.
  2. Inside POST, start the message stream with the TypeScript SDK, then return a new Response wrapping a ReadableStream that 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.
  3. Forward only text_delta event payloads into the stream. Skip message_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.
  4. Accumulate input_json_delta per content-block index if the route also supports tool use; only JSON-parse at content_block_stop. Parsing a partial fragment throws.
  5. Close the stream controller on message_stop and on errors. An unclosed controller leaves the fetch hanging on the client.
  6. Set the response Content-Type to text/event-stream when 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.

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 1 · 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>