Route Handlers
Full-stack app/api/*/route.ts handlers, rewrites and local daemon proxying.
Route handlers define API endpoints in the app directory with the Web Request and Response APIs.
Convention
export function GET(): Response { return Response.json({ status: "ok" });}Export GET, POST, PUT, PATCH, DELETE, HEAD or OPTIONS. Handlers run on text dev, text start and every server deploy adapter, after middleware. Cache GET handlers with route segment config.
Dynamic handlers
export async function GET(_req: Request, { params }: { params: { id: string } }) { const session = await db.sessions.find(params.id); return session ? Response.json(session) : new Response("Not found", { status: 404 });}params values are decoded. A path with an encoded slash or backslash (%2F, %5C) gets a 400, so pass IDs that can contain / in a query parameter or encode them as base64url.
Streaming
Return a ReadableStream for server-sent events:
export function GET() { let n = 0; const stream = new ReadableStream({ start(c) { setInterval(() => c.enqueue(`data: ${n++}\n\n`), 1000); }, }); return new Response(stream, { headers: { "content-type": "text/event-stream" } });}Rewrites
External destinations are proxied by the server, so the browser makes no cross-origin request.
export default defineConfig({ rewrites: [{ source: "/api/opencode/:path*", destination: "http://127.0.0.1:4096/:path*" }],});Local daemon proxying
Use proxy to reach a process on your machine:
export default defineConfig({ proxy: { "/api/opencode": { target: "http://127.0.0.1:4096", changeOrigin: true } },});This is how the OpenCode template connects to a local server.