Response Helpers
All response helpers take an IAppEvent as the first argument. Most send helpers return a Response object. Header helpers mutate event.response.headers in place.
Send Helpers
sendRedirect
Redirect the client to another URL. Sends an HTML body with a <meta> refresh as a fallback.
declare function sendRedirect(
event: IAppEvent,
location: string,
statusCode?: number,
): Response;return sendRedirect(event, '/login', 302);sendFile
Send a file with support for range requests, ETag generation, and automatic content-type detection.
declare function sendFile(
event: IAppEvent,
options: SendFileOptions,
): Promise<Response>;The SendFileOptions type:
type SendFileOptions = {
stats: () => Promise<SendFileStats> | SendFileStats;
content: (
options: SendFileContentOptions,
) => Promise<ReadableStream | ArrayBuffer | Uint8Array> | ReadableStream | ArrayBuffer | Uint8Array;
disposition?: 'attachment' | 'inline';
/** @deprecated Use `disposition: 'attachment'` instead. */
attachment?: boolean;
name?: string;
};import fs from 'node:fs/promises';
import { createReadStream } from 'node:fs';
import { Readable } from 'node:stream';
return await sendFile(event, {
stats: () => fs.stat(filePath),
content: (opts) => Readable.toWeb(createReadStream(filePath, opts)) as ReadableStream,
name: 'report.pdf',
disposition: 'attachment', // 'inline' to render in-browser with a suggested save name
});sendStream
Wrap a ReadableStream in a Response.
declare function sendStream(
event: IAppEvent,
stream: ReadableStream,
): Response;const stream = new ReadableStream({ /* ... */ });
return sendStream(event, stream);sendFormat
Perform content negotiation and send the response in the format the client prefers. Falls back to the default handler if no format matches.
declare function sendFormat(
event: IAppEvent,
formats: {
default: () => unknown;
[contentType: string]: () => unknown;
},
): Response | unknown | undefined;return sendFormat(event, {
default: () => ({ ok: true }),
'application/json': () => ({ ok: true }),
'text/html': () => '<p>OK</p>',
});Header Helpers
setResponseHeaderAttachment
Set the Content-Disposition header to attachment. When a filename is provided, adds the filename (and, for non-ASCII names, filename*=UTF-8''…) directive per RFC 6266 and sets Content-Type based on the file extension.
declare function setResponseHeaderAttachment(
event: IAppEvent,
filename?: string,
): void;setResponseHeaderAttachment(event, 'data.csv');
// Content-Disposition: attachment; filename=data.csvsetResponseHeaderInline
Set the Content-Disposition header to inline. When a filename is provided, adds the filename (and, for non-ASCII names, filename*=UTF-8''…) directive per RFC 6266 and sets Content-Type based on the file extension, following the same encoding rules as setResponseHeaderAttachment. Use this when you want the browser to render the response natively (PDF viewer, image, video) but still suggest a filename if the user later saves it.
declare function setResponseHeaderInline(
event: IAppEvent,
filename?: string,
): void;setResponseHeaderInline(event, 'invoice.pdf');
// Content-Disposition: inline; filename=invoice.pdfcreateContentDisposition
Build a Content-Disposition header value as a string, with RFC 6266 / RFC 5987 encoding for non-US-ASCII filenames. Pure function — does not touch the event. Use this when you need the raw header value (e.g. inside a multipart writer) rather than mutating event.response.headers.
declare function createContentDisposition(
filename?: string,
options?: ContentDispositionCreateOptions,
): string;
type ContentDispositionCreateOptions = {
type?: 'attachment' | 'inline'; // default: 'attachment'
fallback?: string | boolean; // default: true
};createContentDisposition('plans.pdf');
// 'attachment; filename=plans.pdf'
createContentDisposition('€ rates.pdf', { type: 'inline' });
// "inline; filename=\"? rates.pdf\"; filename*=UTF-8''%E2%82%AC%20rates.pdf"parseContentDisposition
Parse a Content-Disposition header value into its type and parameters, decoding RFC 5987 / RFC 8187 extended parameters by default. Accepts null / undefined (as returned by Headers.get() when the header is absent) and returns null in that case, so callers don't need a separate null-check.
declare function parseContentDisposition(
header: string,
options?: ContentDispositionParseOptions,
): ContentDisposition;
declare function parseContentDisposition(
header: string | null | undefined,
options?: ContentDispositionParseOptions,
): ContentDisposition | null;
type ContentDisposition = {
type: string;
parameters: Record<string, string>;
};
type ContentDispositionParseOptions = {
extended?: boolean; // decode filename*=; default: true
multipart?: boolean; // multipart/form-data grammar; default: false
};parseContentDisposition('attachment; filename="plans.pdf"');
// { type: 'attachment', parameters: { filename: 'plans.pdf' } }
parseContentDisposition("attachment; filename*=UTF-8''%E2%82%AC%20rates.pdf");
// { type: 'attachment', parameters: { filename: '€ rates.pdf' } }
parseContentDisposition(event.request.headers.get('content-disposition'));
// null when the header is missingIf the underlying parser throws, the error is rethrown as an AppError with HTTP status 400 and the original error attached as cause — suitable for surfacing through routup's error handler when parsing untrusted request headers.
setResponseHeaderContentType
Set the Content-Type response header. Optionally skip if a content type is already set.
declare function setResponseHeaderContentType(
event: IAppEvent,
type: string,
ifNotExists?: boolean,
): void;setResponseHeaderContentType(event, 'application/json');setResponseCacheHeaders
Set Cache-Control and Last-Modified headers based on the provided options.
declare function setResponseCacheHeaders(
event: IAppEvent,
options?: ResponseCacheHeadersOptions,
): void;The ResponseCacheHeadersOptions type:
type ResponseCacheHeadersOptions = {
maxAge?: number;
modifiedTime?: string | Date;
cacheControls?: string[];
};setResponseCacheHeaders(event, {
maxAge: 3600,
modifiedTime: stats.mtime,
});appendResponseHeader
Append a value to an existing response header (or create it).
declare function appendResponseHeader(
event: IAppEvent,
name: string,
value: string | string[],
): void;appendResponseHeader(event, 'Set-Cookie', 'session=abc; Path=/');appendResponseHeaderDirective
Append a directive to an existing response header value (or create the header). Deduplicates directives.
declare function appendResponseHeaderDirective(
event: IAppEvent,
name: string,
value: string | string[],
): void;appendResponseHeaderDirective(event, 'Cache-Control', 'no-cache');Status Helpers
isResponseGone
Check whether the response has already been dispatched (i.e., event.dispatched is true).
declare function isResponseGone(event: IAppEvent): boolean;setResponseGone
Mark the response as dispatched.
declare function setResponseGone(event: IAppEvent): void;Event Stream (SSE)
createEventStream
Create a Server-Sent Events stream. Returns a handle with methods to write events, end the stream, and the underlying Response.
declare function createEventStream(
event: IAppEvent,
options?: EventStreamOptions,
): EventStreamHandle;The EventStreamOptions type:
type EventStreamOptions = {
maxMessageSize?: number;
};The EventStreamHandle type:
type EventStreamHandle = {
write(message: string | EventStreamMessage): void;
end(): void;
response: Response;
};
type EventStreamMessage = {
id?: string;
retry?: number;
data: string;
event?: string;
};import { defineCoreHandler, createEventStream } from 'routup';
defineCoreHandler((event) => {
const stream = createEventStream(event);
let count = 0;
const interval = setInterval(() => {
stream.write(`count: ${count}`);
count++;
if (count > 100) {
stream.end();
clearInterval(interval);
}
}, 1000);
return stream.response;
});Utility
setResponseContentTypeByFileName
Set the Content-Type header based on a file's extension.
declare function setResponseContentTypeByFileName(
event: IAppEvent,
fileName: string,
): void;setResponseContentTypeByFileName(event, 'image.png');