or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

advanced-features.mdcore-framework.mderror-handling.mdevent-handling.mdhandlers-middleware.mdindex.mdrequest-processing.mdresponse-handling.mdruntime-adapters.mdweb-utilities.md
tile.json

event-handling.mddocs/

Event Handling

H3's event system provides a unified request/response context across all JavaScript runtimes with type-safe event manipulation and utilities.

Capabilities

H3Event Class

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 };
});

HTTPEvent Type

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;
};

Event Utilities

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);

Base Path Utilities

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 /v1

Event Context

H3EventContext Interface

Context 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" };
});

Server Request Types

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;
}

H3EventResponse

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 };
});

Request Fingerprinting

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 };
});