H3's event system provides a unified request/response context across all JavaScript runtimes with type-safe event manipulation and utilities.
The core event class representing HTTP request/response context.
/**
* Represents HTTP request/response context across all runtimes
*/
class H3Event {
/**
* The incoming server request
*/
req: TypedServerRequest;
/**
* Parsed request URL
*/
url: URL;
/**
* Event context for storing custom data
*/
context: H3EventContext;
/**
* Reference to the H3 application instance
*/
app?: H3Core;
/**
* Response object for setting headers and status
*/
res: H3EventResponse;
/**
* Runtime-specific context information
*/
runtime?: ServerRuntimeContext;
/**
* Wait for an async operation to complete (useful for cleanup)
* @param promise - Promise to wait for
*/
waitUntil(promise: Promise<any>): void;
/**
* String representation of the event
* @returns String representation
*/
toString(): string;
/**
* JSON representation of the event
* @returns JSON string
*/
toJSON(): string;
}Usage Examples:
import { defineHandler, H3Event } from "h3";
const handler = defineHandler(async (event: H3Event) => {
// Access request properties
console.log(`Method: ${event.req.method}`);
console.log(`URL: ${event.url.pathname}`);
console.log(`Search: ${event.url.searchParams.get("q")}`);
// Store data in context
event.context.userId = "123";
event.context.startTime = Date.now();
// Set response headers
event.res.setHeader("X-Custom-Header", "value");
// Wait for cleanup
event.waitUntil(
Promise.resolve().then(() => {
console.log("Cleanup completed");
})
);
return { success: true };
});Type for objects that have a request property, commonly used in utility functions.
/**
* Type representing an object with a request property
*/
type HTTPEvent = {
req: ServerRequest;
[key: string]: any;
};Utility functions for working with H3 events.
/**
* Check if input is an H3Event instance
* @param input - Value to check
* @returns True if input is H3Event
*/
function isEvent(input: any): input is H3Event;
/**
* Check if input has a req property (HTTPEvent)
* @param input - Value to check
* @returns True if input is HTTPEvent
*/
function isHTTPEvent(input: any): input is HTTPEvent;
/**
* Get the context from an event
* @param event - H3Event or HTTPEvent
* @returns Event context
*/
function getEventContext<T>(event: HTTPEvent | H3Event): T;
/**
* Create a mock H3Event for testing
* @param request - Request URL string, URL object, or Request object
* @param options - Optional request init and H3 context
* @returns Mock H3Event instance
*/
function mockEvent(
request: string | URL | Request,
options?: RequestInit & { h3?: H3EventContext }
): H3Event;Usage Examples:
import { isEvent, isHTTPEvent, getEventContext, mockEvent } from "h3";
// Type checking
function processEvent(event: unknown) {
if (isEvent(event)) {
// TypeScript knows this is H3Event
console.log(event.url.pathname);
} else if (isHTTPEvent(event)) {
// TypeScript knows this has req property
console.log(event.req.method);
}
}
// Context management
const handler = defineHandler((event) => {
const context = getEventContext<{ userId?: string }>(event);
context.userId = "123";
return { userId: context.userId };
});
// Testing with mock events
const mockEvent1 = mockEvent("http://localhost:3000/api/test", {
method: "POST",
body: JSON.stringify({ test: true }),
headers: { "content-type": "application/json" },
h3: { customProp: "value" }
});
// Use mock event in tests
const result = await handler(mockEvent1);Add base paths to handlers or applications.
/**
* Add a base path to a handler or H3 application
* @param base - Base path to prepend
* @param input - Event handler or H3 instance
* @returns Event handler with base path applied
*/
function withBase(base: string, input: EventHandler | H3): EventHandler;Usage Examples:
import { withBase, defineHandler } from "h3";
// Add base path to handler
const apiHandler = defineHandler(() => ({ message: "API endpoint" }));
const versionedHandler = withBase("/v1", apiHandler);
// Add base path to entire app
const apiApp = new H3();
apiApp.get("/users", () => ({ users: [] }));
const versionedApp = withBase("/v1", apiApp);
// Use in main app
const mainApp = new H3();
mainApp.use(versionedHandler); // Available at /v1
mainApp.use(versionedApp); // All routes prefixed with /v1Context object for storing custom data during request processing.
/**
* Event context for storing custom data
*/
interface H3EventContext {
[key: string]: any;
}Usage Examples:
// Store authentication info
const authHandler = defineHandler((event) => {
event.context.user = { id: "123", name: "John" };
event.context.permissions = ["read", "write"];
});
// Access in later middleware
const protectedHandler = defineHandler((event) => {
const user = event.context.user;
const permissions = event.context.permissions;
if (!user || !permissions.includes("read")) {
throw HTTPError.status(403, "Forbidden");
}
return { data: "protected data" };
});Types for server requests across different runtimes.
/**
* Typed server request with additional properties
*/
interface TypedServerRequest extends ServerRequest {
method: HTTPMethod;
url: string;
headers: Headers;
body?: ReadableStream<Uint8Array> | null;
}
/**
* Server runtime context information
*/
interface ServerRuntimeContext {
runtime?: string;
version?: string;
platform?: string;
[key: string]: any;
}Response object for setting headers and status.
/**
* Event response object for setting headers and status
*/
interface H3EventResponse {
/**
* Set a response header
* @param name - Header name
* @param value - Header value
*/
setHeader(name: string, value: string): void;
/**
* Get a response header
* @param name - Header name
* @returns Header value or undefined
*/
getHeader(name: string): string | undefined;
/**
* Remove a response header
* @param name - Header name
*/
removeHeader(name: string): void;
/**
* Set response status code
* @param code - HTTP status code
*/
setStatus(code: number): void;
/**
* Get response status code
* @returns HTTP status code
*/
getStatus(): number;
}Usage Examples:
const handler = defineHandler((event) => {
// Set response headers
event.res.setHeader("Cache-Control", "max-age=3600");
event.res.setHeader("X-API-Version", "1.0");
// Set status code
event.res.setStatus(201);
// Check existing headers
const contentType = event.res.getHeader("content-type");
if (!contentType) {
event.res.setHeader("content-type", "application/json");
}
return { created: true };
});Generate unique fingerprints for requests based on various criteria.
/**
* Generate a unique fingerprint for a request
* @param event - HTTP event
* @param options - Fingerprinting options
* @returns Unique request fingerprint string
*/
function getRequestFingerprint(
event: HTTPEvent,
options?: RequestFingerprintOptions
): string;
interface RequestFingerprintOptions {
/**
* Include IP address in fingerprint
*/
ip?: boolean;
/**
* Include User-Agent header in fingerprint
*/
userAgent?: boolean;
/**
* Include request path in fingerprint
*/
path?: boolean;
/**
* Include request method in fingerprint
*/
method?: boolean;
/**
* Additional headers to include
*/
headers?: string[];
}Usage Examples:
import { getRequestFingerprint } from "h3";
const handler = defineHandler((event) => {
// Basic fingerprint
const basicFingerprint = getRequestFingerprint(event);
// Detailed fingerprint
const detailedFingerprint = getRequestFingerprint(event, {
ip: true,
userAgent: true,
path: true,
method: true,
headers: ["authorization", "x-api-key"]
});
// Use for rate limiting, caching, etc.
console.log(`Request fingerprint: ${basicFingerprint}`);
return { fingerprint: basicFingerprint };
});