Connect a BTST API handler to TanStack Start without buffering its response, losing authentication headers, or confusing the page and API mounts.

A streaming endpoint can return HTTP 200 and still feel broken: the first text arrives only after generation finishes, the client cannot parse the response, or authenticated history calls lose their session. Start by checking how the framework route forwards the request and response.
In a BTST integration, the backend handler already owns the HTTP response. TanStack Start needs to route requests to that handler while preserving its body stream, status, and headers.
For a backend configured at /api/data, the BTST 3.0.0 CLI template uses a TanStack catch-all server route:
// src/routes/api/data/$.ts
import { createFileRoute } from "@tanstack/react-router";
import { toTanStackHandlers } from "@btst/stack/tanstack";
import { handler } from "@/lib/stack";
export const Route = createFileRoute("/api/data/$")({
server: { handlers: toTanStackHandlers(handler) },
});
This assumes an existing TanStack Start project, its generated route types, the @/ alias, and a configured server stack exporting handler. Keep credentials and database setup in that server module. The snippet is the route integration, not a complete app.
The released BTST handler adapter forwards the original Request for GET, POST, PUT, PATCH, and DELETE. Each method returns the backend handler's result directly. It does not read the response into a string first.
TanStack's server-route documentation describes the server.handlers convention. Use a server route for this HTTP endpoint; the BTST browser client expects the plugin's HTTP contract.
The backend basePath and client api.basePath must identify the same API mount. Client site.basePath identifies the pages instead. For example:
| Configuration | Example | Purpose |
|---|---|---|
Backend basePath | /api/data | Receives plugin API requests |
Client api.basePath | /api/data | Sends browser and loader API calls |
Client site.basePath | /p | Builds plugin page URLs |
| TanStack server route | /api/data/$ | Forwards API requests to BTST |
A chat page under /p does not imply that its stream should POST to the page URL. Inspect the actual request URL in the browser Network panel. If it returns your site's HTML shell, fix routing before changing the model configuration.
Do not add await response.text() or await response.json() around a streaming response just to log it. Those operations consume the body and wait for completion. Wrapping the consumed result in a new response can also discard status and protocol headers.
AI Chat in this release uses the AI SDK UI message stream. That carries structured chat events, not just arbitrary text chunks. Keep the plugin's matching client and server transport together; replacing one side with a plain-text reader changes the contract.
Middleware should also avoid consuming the incoming request body before BTST reads it. Forwarding the original request preserves the cookies and headers that the server identity resolver needs. Configure allowed origins and credentials deliberately for cross-origin deployments, and keep privileged headers out of browser-visible configuration.
Use this sequence on a development or staging conversation with non-sensitive input:
Avoid logging full request headers, prompts, or stream bodies during diagnosis. Status, elapsed time, a correlation ID, and a coarse failure category are usually enough to find which layer failed.
Use BTST installation for complete framework wiring and AI Chat documentation for model and persistence configuration. If history is the remaining problem, check private conversation ownership and transactions before changing the streaming adapter.