# 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.
