BlazeResponse is constructed once per request inside app.fetch and passed alongside req through every handler and middleware. Internally it holds a Promise that app.fetch awaits. Calling any terminal method — res.json(), res.send(), res.html(), res.redirect(), res.stream(), or res.raw() — resolves that promise and sends the response to the client, mirroring the Express res.send() pattern. Calling a terminal method more than once is safe: subsequent calls are silently ignored.
Response methods
onSend hook
res.onSend() lets middleware transform the outgoing Response — for example, to inject headers — without needing to intercept the terminal call itself. Register hooks before the terminal method is called; each hook receives the current Response and must return a Response.
headersSent guard
Checkres.headersSent in middleware that may execute after a response has already been sent — for example, in cleanup logic:
Sending JSON
res.json() is the most common response method. Pass any serialisable value and Blaze handles JSON.stringify and the Content-Type header for you.
Sending text and HTML
Useres.send() for plain text and res.html() for full HTML documents or fragments.
Redirects
res.redirect() issues an HTTP redirect. The default status is 302 (temporary). Pass a second argument to use a different 3xx code.
Streaming responses
res.stream() starts the HTTP response immediately and pipes data to the client as your fn writes to a WritableStream. Use it for server-sent events (SSE), large file transfers, or streaming AI completions.
- Server-sent events
- Streaming AI
- R2 file stream
Setting headers and cookies
res.header() and res.cookie() are chainable and can be combined with any terminal method.
Headers
Cookies
res.cookie() accepts a CookieOptions object as its third argument:
string
The
Domain attribute of the cookie. Restricts the cookie to the given domain and its subdomains.Date
The
Expires attribute. Sets an absolute expiry time for the cookie.boolean
When
true, sets the HttpOnly attribute to prevent client-side script access.number
The
Max-Age attribute in seconds. Takes precedence over expires in modern browsers.string
The
Path attribute. Restricts the cookie to the given path prefix. Defaults to /.boolean
When
true, sets the Secure attribute so the cookie is only sent over HTTPS."Strict" | "Lax" | "None"
The
SameSite attribute. Controls cross-site cookie sending. Use 'None' with secure: true for cross-origin requests.boolean
When
true, sets the Partitioned attribute (CHIPS). Required for cross-site cookies in some browser privacy modes.Chaining status
res.status(code) returns res, so you can chain it directly before any terminal method. You can also pass status as the second argument to res.json() and res.send() for a more compact style.
res.status() only sets the status code — it does not send the response.
You must always follow it with a terminal method (json, send, html,
redirect, or stream).