### Setup and Development Commands for H3 Source: https://github.com/h3js/h3/blob/main/AGENTS.md Commands for setting up the project, running tests, building, linting, formatting, and benchmarking H3. Ensure corepack is enabled and pnpm is installed for these commands. ```bash # Setup corepack enable && pnpm install ``` ```bash # Development pnpm dev # vitest watch mode pnpm vitest run # run specific test pnpm test # full suite (lint + typecheck + coverage) pnpm build # build with obuild pnpm lint # oxlint + oxfmt --check (lint + typecheck) pnpm fmt # automd + oxlint --fix + oxfmt pnpm bench:node # node benchmarks pnpm bench:bun # bun benchmarks ``` -------------------------------- ### Basic Static Asset Serving Setup in H3 Source: https://github.com/h3js/h3/blob/main/docs/4.examples/serve-static-assets.md Initial setup for serving static assets. Requires implementing `getContents` and `getMeta` for file retrieval and metadata. ```typescript import { H3, serveStatic } from "h3"; const app = new H3(); app.use("/public/**", (event) => { return serveStatic(event, { getContents: (id) => { // TODO }, getMeta: (id) => { // TODO }, }); }); ``` -------------------------------- ### Start server listener Source: https://github.com/h3js/h3/blob/main/docs/1.guide/0.index.md Starts the H3 server on a specified port using the universal serve method. ```js serve(app, { port: 3000 }); ``` -------------------------------- ### Create a simple H3 server with a GET route Source: https://github.com/h3js/h3/blob/main/docs/99.blog/2.v2-beta.md Instantiate `H3` and define routes using methods like `get`. The `serve` function from `h3` can then be used to run the H3 application on a specified port. ```js import { H3, serve } from "h3"; const app = new H3().get("/", () => "⚡️ Tadaa!"); serve(app, { port: 3000 }); ``` -------------------------------- ### Full WebSocket Example with CrossWS in H3 Source: https://github.com/h3js/h3/blob/main/docs/1.guide/901.advanced/2.websocket.md A comprehensive example demonstrating WebSocket functionality including connection, message handling, and broadcasting. It serves an HTML file for a client interface. ```js import { H3, serve, defineWebSocketHandler } from "h3"; import { plugin as ws } from "crossws/server"; export const app = new H3(); const demoURL = "https://raw.githubusercontent.com/h3js/crossws/refs/heads/main/playground/public/index.html"; app.get("/", () => fetch(demoURL).then( (res) => new Response(res.body, { headers: { "Content-Type": "text/html" } }), ), ); app.get( "/_ws", defineWebSocketHandler({ // upgrade(req) {}, open(peer) { console.log("[open]", peer); // Send welcome to the new client peer.send("Welcome to the server!"); // Join new client to the "chat" channel peer.subscribe("chat"); // Notify every other connected client peer.publish("chat", `[system] ${peer} joined!`); }, message(peer, message) { console.log("[message]", peer); if (message.text() === "ping") { // Reply to the client with a ping response peer.send("pong"); return; } // The server re-broadcasts incoming messages to everyone peer.publish("chat", `[${peer}] ${message}`); // Echo the message back to the sender peer.send(message); }, close(peer) { console.log("[close]", peer); peer.publish("chat", `[system] ${peer} has left the chat!`); peer.unsubscribe("chat"); }, }), ); serve(app, { plugins: [ws({ resolve: async (req) => (await app.fetch(req)).crossws })], }); ``` -------------------------------- ### Create a Basic ReadableStream Source: https://github.com/h3js/h3/blob/main/docs/4.examples/stream-response.md Initialize a ReadableStream. This example shows the basic structure for creating a stream. ```ts const stream = new ReadableStream(); ``` -------------------------------- ### Create and serve an H3 application Source: https://github.com/h3js/h3/blob/main/docs/1.guide/0.index.md Initializes an H3 instance, defines a root route, and starts the server on port 3000. ```ts import { H3, serve } from "h3"; const app = new H3().get("/", (event) => "⚡️ Tadaa!"); serve(app, { port: 3000 }); ``` -------------------------------- ### Registering GET routes with H3 methods Source: https://github.com/h3js/h3/blob/main/docs/1.guide/1.basics/2.routing.md Register a route for the GET method using either the shorthand method or the generic on method. ```js app.get("/hello", () => "Hello world!"); ``` ```js app.on("GET", "/hello", () => "Hello world!"); ``` -------------------------------- ### onResponse Middleware Example Source: https://github.com/h3js/h3/blob/main/docs/99.blog/2.v2-beta.md Log response details using the `onResponse` middleware. This middleware is executed after a response is generated. ```js import { H3, onResponse } from "h3"; const app = new H3().use( onResponse((response, event) => { console.log(`Response: [${event.req.method}] ${event.url.pathname}`, body); }), ); ``` -------------------------------- ### onRequest Middleware Example Source: https://github.com/h3js/h3/blob/main/docs/99.blog/2.v2-beta.md Log request details using the `onRequest` middleware. This middleware is executed for every incoming request. ```js import { H3, onRequest } from "h3"; const app = new H3().use( onRequest((event) => { console.log(`Request: [${event.req.method}] ${event.url.pathname}`); }), ); ``` -------------------------------- ### Serve a basic HTTP server with srvx Source: https://github.com/h3js/h3/blob/main/docs/99.blog/2.v2-beta.md Use the `serve` function from `srvx` to start a web server. It dynamically selects the appropriate adapter for the runtime. The `fetch` handler receives a `Request` object and should return a `Response`. ```js import { serve } from "srvx"; serve({ port: 3000, // tls: { cert: "server.crt", key: "server.key" } fetch(req) { // Server Extensions: req.ip, req.waitUntil(), req.runtime?.{bun,deno,node,cloudflare,...} return new Response("👋 Hello there!"); }, }); ``` -------------------------------- ### H3.[method] Shortcut Source: https://github.com/h3js/h3/blob/main/docs/1.guide/900.api/1.h3.md Provides shortcut methods (e.g., `get`, `post`) for registering route handlers for specific HTTP methods. ```APIDOC ## H3.[method] Shortcut ### Description Register route handler for specific HTTP method (shortcut for `app.on(method, ...)`). ### Request Example ```js const app = new H3().get("/", () => "OK"); ``` ``` -------------------------------- ### Chaining Middleware with next() Source: https://github.com/h3js/h3/blob/main/docs/99.blog/2.v2-beta.md Use the `next()` function to compose middleware in H3. This example shows how to execute code before and after the response is generated. ```js import { H3 } from "h3"; const app = new H3().use(async (event, next) => { // ... before response ... const body = await next(); // ... after response ... event.res.headers.append("x-middleware", "works"); event.waitUntil(sendMetrics(event)); return body; }); ``` -------------------------------- ### Initialize H3 App with Listhen for Development Source: https://github.com/h3js/h3/blob/main/docs/99.blog/1.v1.8.md Use unjs/listhen to start a development server for H3 apps with TypeScript support and Hot Module Replacement (HMR). Ensure you have an index.ts file defining your app. ```typescript import { createApp, eventHandler } from "h3"; export const app = createApp(); app.use("/", () => "Hello world!"); ``` -------------------------------- ### Defining and Registering a Plugin Source: https://github.com/h3js/h3/blob/main/docs/99.blog/2.v2-beta.md Create reusable plugins using `definePlugin`. This example shows a logger plugin that conditionally logs requests based on debug configuration. ```js import { H3, serve, definePlugin } from "h3"; const logger = definePlugin((h3, _options) => { if (h3.config.debug) { h3.use((req) => { console.log(`[${req.method}] ${req.url}`); }); } }); const app = new H3({ debug: true }).register(logger()).all("/**", () => "Hello!"); ``` -------------------------------- ### Get Query Parameters Source: https://github.com/h3js/h3/blob/main/docs/2.utils/1.request.md Retrieves and parses the query string parameters from the request URL. ```typescript app.get("/", (event) => { const query = getQuery(event); // { key: "value", key2: ["value1", "value2"] } }); ``` -------------------------------- ### fetchWithEvent Source: https://github.com/h3js/h3/blob/main/docs/2.utils/5.proxy.md Makes a fetch request using the event's context and headers. If the URL starts with '/', it's treated as an internal sub-request. ```APIDOC ## fetchWithEvent(event, url, init?) ### Description Make a fetch request with the event's context and headers. If the `url` starts with `/`, the request is dispatched internally via `event.app.fetch()` (sub-request) and never leaves the process. ### Security Never pass unsanitized user input as the `url`. Callers are responsible for validating and restricting the URL. ``` -------------------------------- ### Define a route handler Source: https://github.com/h3js/h3/blob/main/docs/1.guide/0.index.md Registers a GET handler for the root path that returns a JSON object. ```ts app.get("/", (event) => { return { message: "⚡️ Tadaa!" }; }); ``` -------------------------------- ### Register Route Handlers Source: https://github.com/h3js/h3/blob/main/docs/1.guide/900.api/1.h3.md Register handlers for specific HTTP methods or all methods using the on, get, or all methods. ```javascript const app = new H3().on("GET", "/", () => "OK"); ``` ```javascript const app = new H3().get("/", () => "OK"); ``` ```javascript const app = new H3().all("/", () => "OK"); ``` -------------------------------- ### Implement File Reading and Metadata for Static Assets in H3 Source: https://github.com/h3js/h3/blob/main/docs/4.examples/serve-static-assets.md Complete implementation for serving static assets, including reading file contents with `readFile` and getting metadata with `stat`. Supports caching via `Last-Modified` and etags. ```typescript import { stat, readFile } from "node:fs/promises"; import { join } from "node:path"; import { H3, serve, serveStatic } from "h3"; const app = new H3(); app.use("/public/**", (event) => { return serveStatic(event, { indexNames: ["/index.html"], getContents: (id) => readFile(join("public", id)), getMeta: async (id) => { const stats = await stat(join("public", id)).catch(() => {}); if (stats?.isFile()) { return { size: stats.size, mtime: stats.mtimeMs, }; } }, }); }); serve(app); ``` -------------------------------- ### Define and Register WebSocket Handler in H3 Source: https://github.com/h3js/h3/blob/main/docs/1.guide/901.advanced/2.websocket.md Defines a basic WebSocket handler and registers it to a route. Requires CrossWS plugin setup in the `serve` function. ```js import { H3, serve, defineWebSocketHandler } from "h3"; import { plugin as ws } from "crossws/server"; const app = new H3(); app.get("/_ws", defineWebSocketHandler({ message: console.log })); serve(app, { plugins: [ws({ resolve: async (req) => (await app.fetch(req)).crossws })], }); ``` -------------------------------- ### onError Middleware Example Source: https://github.com/h3js/h3/blob/main/docs/99.blog/2.v2-beta.md Handle errors gracefully using the `onError` middleware. This middleware is executed when an error occurs during request processing. ```js import { H3, onError } from "h3"; const app = new H3().use( onError((error, event) => { console.error(`[${event.req.method}] ${event.url.pathname} !! ${error.message}`); }), ); ``` -------------------------------- ### Proxy Request with Event Context Source: https://github.com/h3js/h3/blob/main/docs/2.utils/5.proxy.md Use `fetchWithEvent` to make fetch requests that include the event's context and headers. Internal requests starting with '/' are handled via `event.app.fetch()`. ```typescript fetchWithEvent(event, url, init?) ``` -------------------------------- ### Get Full Request URL Source: https://github.com/h3js/h3/blob/main/docs/2.utils/1.request.md Constructs the complete request URL, considering `x-forwarded-host` and `x-forwarded-proto` headers. Host and proto forwarding can be selectively disabled. ```typescript app.get("/", (event) => { const url = getRequestURL(event); // "https://example.com/path" }); ``` -------------------------------- ### Proxy Request to Target URL Source: https://github.com/h3js/h3/blob/main/docs/2.utils/5.proxy.md Use `proxy` to forward requests to a target URL and send the response back to the client. Internal requests starting with '/' are handled via `event.app.fetch()`. ```typescript proxy(event, target, opts) ``` -------------------------------- ### H3 Class Initialization Source: https://github.com/h3js/h3/blob/main/docs/1.guide/900.api/1.h3.md Demonstrates how to create a new H3 app instance with optional configuration. ```APIDOC ## H3 Class Initialization ### Description Create a new H3 app instance using `new H3()` with optional configuration. ### Request Example ```js import { H3 } from "h3"; const app = new H3({ /* optional config */ }); ``` ``` -------------------------------- ### Run H3 server in different runtimes Source: https://github.com/h3js/h3/blob/main/docs/1.guide/0.index.md Commands to execute the server file using Node.js, Deno, or Bun. ```bash node --watch ./server.mjs ``` ```bash deno run -A --watch ./server.mjs ``` ```bash bun run --watch server.mjs ``` -------------------------------- ### Initialize H3 Application Source: https://github.com/h3js/h3/blob/main/docs/1.guide/900.api/1.h3.md Create a new instance of the H3 application, optionally passing a configuration object. ```javascript import { H3 } from "h3"; const app = new H3({ /* optional config */ }); ``` -------------------------------- ### Get Router Parameter Source: https://github.com/h3js/h3/blob/main/docs/2.utils/1.request.md Retrieves a route parameter by its name. Optionally decodes the parameter using `decodeURI`. ```typescript app.get("/", (event) => { const param = getRouterParam(event, "key"); }); ``` -------------------------------- ### Getting Request Pathname in H3 Source: https://github.com/h3js/h3/blob/main/docs/5.migration/0.index.md Obtain the request pathname using `event.url.pathname`. This replaces the deprecated `event.path` property. ```javascript event.url.pathname ``` -------------------------------- ### H3 Options Source: https://github.com/h3js/h3/blob/main/docs/1.guide/900.api/1.h3.md Global app configuration options available during H3 initialization. ```APIDOC ## H3 Options ### Description You can pass global app configuration when initializing an app. ### Supported Options - `debug`: Displays debugging stack traces in HTTP responses (potentially dangerous for production!). - `silent`: When enabled, console errors for unhandled exceptions will not be displayed. - `plugins`: (see [plugins](/guide/advanced/plugins) for more information) ### Request Example ```js const app = new H3({ debug: true, silent: false }); ``` ``` -------------------------------- ### Registering a route for all HTTP methods Source: https://github.com/h3js/h3/blob/main/docs/1.guide/1.basics/2.routing.md Use the all method to handle any HTTP request method for a specific path. ```js app.all("/hello", (event) => `This is a ${event.req.method} request!`); ``` -------------------------------- ### Get Request Protocol Source: https://github.com/h3js/h3/blob/main/docs/2.utils/1.request.md Determines the request protocol, respecting the `x-forwarded-proto` header unless disabled. Defaults to `http`. ```typescript app.get("/", (event) => { const protocol = getRequestProtocol(event); // "https" }); ``` -------------------------------- ### Get a cookie with H3 Source: https://github.com/h3js/h3/blob/main/docs/4.examples/handle-cookie.md Use getCookie to retrieve a cookie value from the request, returning undefined if the cookie does not exist. ```ts import { getCookie } from "h3"; app.use(async (event) => { const name = getCookie(event, "name"); // do something... return ""; }); ``` -------------------------------- ### Initialize H3 app instance Source: https://github.com/h3js/h3/blob/main/docs/1.guide/0.index.md Creates a new H3 application instance. ```ts const app = new H3(); ``` -------------------------------- ### Creating an H3 App Instance Source: https://github.com/h3js/h3/blob/main/docs/5.migration/0.index.md Instantiate an H3 application using `new H3()`. This replaces the deprecated `createApp` utility. ```javascript const app = new H3() ``` -------------------------------- ### Get matched route parameters Source: https://github.com/h3js/h3/blob/main/docs/2.utils/1.request.md Retrieves route parameters from the event. Use the decode option to automatically decode values. ```ts app.get("/", (event) => { const params = getRouterParams(event); // { key: "value" } }); ``` -------------------------------- ### Write HTTP Early Hints Source: https://github.com/h3js/h3/blob/main/docs/2.utils/2.response.md Writes `HTTP/1.1 103 Early Hints` to the client. In environments without native support, it falls back to setting response headers for CDN usage. ```typescript writeEarlyHints(event, hints) ``` -------------------------------- ### Getting Request Method in H3 Source: https://github.com/h3js/h3/blob/main/docs/5.migration/0.index.md Retrieve the HTTP request method using `event.req.method`. This replaces the deprecated `event.method` property. ```javascript event.req.method ``` -------------------------------- ### H3.all Method Source: https://github.com/h3js/h3/blob/main/docs/1.guide/900.api/1.h3.md Registers a route handler that matches all HTTP methods for a given path. ```APIDOC ## H3.all Method ### Description Register route handler for all HTTP methods. ### Request Example ```js const app = new H3().all("/", () => "OK"); ``` ``` -------------------------------- ### proxy Source: https://github.com/h3js/h3/blob/main/docs/2.utils/5.proxy.md Proxies a request to a target URL and sends the response back to the client. Handles internal sub-requests for URLs starting with '/'. ```APIDOC ## proxy(event, target, opts) ### Description Make a proxy request to a target URL and send the response back to the client. If the `target` starts with `/`, the request is dispatched internally via `event.app.fetch()` (sub-request) and never leaves the process. This bypasses any external security layer (reverse proxy auth, IP allowlisting, mTLS). ### Security Never pass unsanitized user input as the `target`. Callers are responsible for validating and restricting the target URL (e.g. allowlisting hosts, blocking internal paths, enforcing protocol). ``` -------------------------------- ### Get Sanitized Proxy Request Headers Source: https://github.com/h3js/h3/blob/main/docs/2.utils/5.proxy.md Use `getProxyRequestHeaders` to obtain request headers, excluding those known to cause proxying issues. ```typescript getProxyRequestHeaders(event) ``` -------------------------------- ### Preparing Response Headers and Status Source: https://github.com/h3js/h3/blob/main/docs/1.guide/1.basics/5.response.md Use event.res to manually set status codes and headers before returning a response body. ```js defineHandler((event) => { event.res.status = 200; event.res.statusText = "OK"; event.res.headers.set("Content-Type", "text/html"); return "

Hello, World

"; }); ``` -------------------------------- ### Getting Request Headers in H3 Source: https://github.com/h3js/h3/blob/main/docs/5.migration/0.index.md Retrieve all request headers as an object using `Object.fromEntries(event.req.headers.entries())`. This leverages the native `Headers` interface. ```javascript Object.fromEntries(event.req.headers.entries()) ``` -------------------------------- ### Get Request Host Source: https://github.com/h3js/h3/blob/main/docs/2.utils/1.request.md Retrieves the request hostname, optionally using the `x-forwarded-host` header. Returns an empty string if no host is found. ```typescript app.get("/", (event) => { const host = getRequestHost(event); // "example.com" }); ``` -------------------------------- ### H3.mount Method Source: https://github.com/h3js/h3/blob/main/docs/1.guide/900.api/1.h3.md Mounts a sub-application to the main application with a specified prefix. ```APIDOC ## H3.mount Method ### Description Using `.mount` method, you can register a sub-app with prefix. ### Request Example ```js // Assuming subApp is an H3 instance // const app = new H3().mount('/sub', subApp); ``` ``` -------------------------------- ### Initialize a Session Source: https://github.com/h3js/h3/blob/main/docs/4.examples/handle-session.md Use useSession within an event handler to initialize a session. A password is required for encryption. ```js import { useSession } from "h3"; app.use(async (event) => { const session = await useSession(event, { password: "80d42cfb-1cd2-462c-8f17-e3237d9027e9", }); // do something... }); ``` -------------------------------- ### Convert Web handlers to H3 Source: https://github.com/h3js/h3/blob/main/docs/1.guide/1.basics/4.handler.md Use fromWebHandler or app.mount to integrate standard Request/Response handlers into H3. ```js import { H3, fromWebHandler } from "h3"; export const app = new H3(); const webHandler = (request) => new Response("👋 Hello!"); // Using fromWebHandler utiliy app.all("/web", fromWebHandler(webHandler)); // Using simple wrapper app.all("/web", (event) => webHandler(event.req)); // Using app.mount app.mount("/web", webHandler); ``` -------------------------------- ### proxyRequest Source: https://github.com/h3js/h3/blob/main/docs/2.utils/5.proxy.md Proxies the incoming request to a target URL, streaming the body without buffering. Handles internal routing for URLs starting with '/'. ```APIDOC ## proxyRequest(event, target, opts) ### Description Proxy the incoming request to a target URL. If the `target` starts with `/`, the request is handled internally by the app router via `event.app.fetch()` instead of making an external HTTP request. The request body is streamed to the target without buffering. Per the Fetch standard, a request body can only be consumed once, so reading it beforehand (e.g. via `readBody()`, `readFormData()`, or body-reading middleware) locks the stream and proxying fails. If you need to inspect the body and still proxy it, read from a clone and leave the original event untouched. ### Security Never pass unsanitized user input as the `target`. Callers are responsible for validating and restricting the target URL (e.g. allowlisting hosts, blocking internal paths, enforcing protocol). Consider using `bodyLimit()` middleware to prevent large request bodies from consuming excessive resources when proxying untrusted input. ### Example ```ts app.all("/proxy", async (event) => { const body = await event.req.clone().json(); // read from the clone // ...inspect body... return proxyRequest(event, "/target"); // original stream still intact }); ``` ``` -------------------------------- ### Create Basic Auth Middleware Source: https://github.com/h3js/h3/blob/main/docs/2.utils/4.security.md Use this to create a middleware for basic authentication. It requires the `h3` package and the `basicAuth` utility. ```typescript import { H3, serve, basicAuth } from "h3"; const auth = basicAuth({ password: "test" }); app.get("/", (event) => `Hello ${event.context.basicAuth?.username}!`, [auth]); serve(app, { port: 3000 }); ``` -------------------------------- ### Cookie Management API Source: https://github.com/h3js/h3/blob/main/docs/2.utils/3.cookie.md Provides functions to interact with HTTP cookies, including setting, getting, and deleting them. Supports both standard and chunked cookies. ```APIDOC ## deleteChunkedCookie(event, name, serializeOptions?) ### Description Remove a set of chunked cookies by name. ### Method Not specified (likely POST or DELETE based on action) ### Endpoint Not specified ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) None specified #### Response Example None ``` ```APIDOC ## deleteCookie(event, name, serializeOptions?) ### Description Remove a cookie by name. ### Method Not specified (likely POST or DELETE based on action) ### Endpoint Not specified ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) None specified #### Response Example None ``` ```APIDOC ## getChunkedCookie(event, name) ### Description Get a chunked cookie value by name. Will join chunks together. ### Method GET ### Endpoint Not specified ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **value** (string) - The concatenated value of the chunked cookie. #### Response Example { "example": "cookie value" } ``` ```APIDOC ## getCookie(event, name) ### Description Get a cookie value by name. ### Method GET ### Endpoint Not specified ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **value** (string) - The value of the cookie. #### Response Example { "example": "cookie value" } ``` ```APIDOC ## getValidatedCookies(event, validate, options?: { onError?: OnValidateError }) ### Description Gets cookies and validates them using a provided function. ### Method GET ### Endpoint Not specified ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **cookies** (object) - An object containing the validated cookies. #### Response Example { "example": "{ cookieName: cookieValue }" } ``` ```APIDOC ## parseCookies(event) ### Description Parse the request to get HTTP Cookie header string and returning an object of all cookie name-value pairs. ### Method GET ### Endpoint Not specified ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **cookies** (object) - An object containing all cookie name-value pairs. #### Response Example { "example": "{ cookieName: cookieValue }" } ``` ```APIDOC ## setChunkedCookie(event, name, value, options?) ### Description Set a cookie value by name. Chunked cookies will be created as needed. ### Method Not specified (likely POST or PUT based on action) ### Endpoint Not specified ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) None specified #### Response Example None ``` ```APIDOC ## setCookie(event, name, value, options?) ### Description Set a cookie value by name. ### Method Not specified (likely POST or PUT based on action) ### Endpoint Not specified ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) None specified #### Response Example None ``` -------------------------------- ### Mount Web Standard Apps (Elysia and Hono) Source: https://github.com/h3js/h3/blob/main/docs/1.guide/1.basics/7.nested-apps.md Mount other web standard server instances like Elysia or Hono under a base URL. The base prefix is removed from the request.url passed to the mounted app. ```javascript import { H3 } from "h3"; import { Hono } from "hono"; import { Elysia } from "elysia"; const app = new H3() .mount( "/elysia", new Elysia().get("/test", () => "Hello Elysia!"), ) .mount( "/hono", new Hono().get("/test", (c) => c.text("Hello Hono!")), ); ``` -------------------------------- ### Applying Base Path to Routes Source: https://github.com/h3js/h3/blob/main/docs/5.migration/0.index.md Use `withBase` to create routes prefixed with a base path. This replaces the deprecated `useBase` utility. ```javascript withBase(basePath, handler) ``` -------------------------------- ### Getting Set-Cookie Header Values Source: https://github.com/h3js/h3/blob/main/docs/5.migration/0.index.md Retrieve all `Set-Cookie` header values as a string array using `headers.getSetCookie()`. This ensures consistent handling of cookie headers. ```javascript event.res.getSetCookie() ``` -------------------------------- ### Getting a Specific Request Header in H3 Source: https://github.com/h3js/h3/blob/main/docs/5.migration/0.index.md Access a specific request header by name using `event.req.headers.get(name)`. This uses the native `Headers` interface. ```javascript event.req.headers.get(name) ``` -------------------------------- ### withBase Utility Source: https://github.com/h3js/h3/blob/main/docs/2.utils/9.more.md Utility to handle base URL stripping for event handlers. ```APIDOC ## withBase(base, input) ### Description Returns a new event handler that removes the base url of the event before calling the original handler. ### Parameters - **base** (string) - Required - The base path to strip. - **input** (EventHandler) - Required - The original event handler. ``` -------------------------------- ### Basic Authentication Middleware Source: https://github.com/h3js/h3/blob/main/docs/99.blog/2.v2-beta.md Implement basic authentication using the `basicAuth` middleware. This requires defining the handler with the middleware and providing a password. ```js import { defineHandler, basicAuth } from "h3"; export default defineHandler({ middleware: [basicAuth({ password: "test" })], handler: (event) => `Hello ${event.context.basicAuth?.username}!`, }); ``` -------------------------------- ### GET /rpc/ws - JSON-RPC 2.0 WebSocket Handler Source: https://github.com/h3js/h3/blob/main/docs/2.utils/6.mcp.md Defines an H3 event handler that implements JSON-RPC 2.0 over WebSocket connections for bi-directional messaging. ```APIDOC ## GET /rpc/ws - JSON-RPC 2.0 WebSocket Handler ### Description Creates an H3 event handler that implements JSON-RPC 2.0 over WebSocket. Each incoming WebSocket text message is processed as a JSON-RPC request, and responses are sent back to the peer. This is an opt-in feature for bi-directional communication. ### Method GET ### Endpoint /rpc/ws ### Parameters #### Request Body (WebSocket Messages) - **methods** (object) - Required - An object containing the methods that will be exposed via JSON-RPC. - **methodName** (function) - Required - The name of the JSON-RPC method. The function receives `params`. - **hooks** (object) - Optional - WebSocket lifecycle hooks. - **open** (function) - Called when a peer connects. - **close** (function) - Called when a peer disconnects. ### Request Example (Client sending a message) ```json { "jsonrpc": "2.0", "method": "echo", "params": { "message": "hello" }, "id": 1 } ``` ### Response (Server sending a message) #### Success Response (WebSocket Message) - **result** (any) - The result of the JSON-RPC method execution. - **id** (number | string | null) - The ID of the request. #### Response Example ```json { "jsonrpc": "2.0", "result": "Received: hello", "id": 1 } ``` ### Example with Hooks ```typescript app.get( "/rpc/ws", defineJsonRpcWebSocketHandler({ methods: { greet: ({ params }) => `Hello, ${params.name}!`, }, hooks: { open(peer) { console.log(`Peer connected: ${peer.id}`); }, close(peer, details) { console.log(`Peer disconnected: ${peer.id}`, details); }, }, }), ); ``` ``` -------------------------------- ### Create Web Handler with H3 Source: https://github.com/h3js/h3/blob/main/docs/99.blog/1.v1.8.md Use `toWebHandler` to convert an H3 application into a web-compatible handler. This allows deployment on runtimes like Cloudflare Workers, Deno Deploy, and Bun. Ensure you import necessary functions from 'h3'. ```typescript import { createApp, eventHandler, toWebHandler } from "https://esm.sh/h3@1.8.0"; const app = createApp(); app.use( "/", eventHandler((event) => "H3 works on edge!"), ); const webHandler = toWebHandler(app); // (Request) => Promise ``` -------------------------------- ### Get Request IP Address Source: https://github.com/h3js/h3/blob/main/docs/2.utils/1.request.md Attempts to determine the client's IP address, optionally using the `x-forwarded-for` header. Defaults to `undefined` if unable to determine. ```typescript app.get("/", (event) => { const ip = getRequestIP(event); // "192.0.2.0" }); ``` -------------------------------- ### Running H3 Tests with Vitest Source: https://github.com/h3js/h3/blob/main/AGENTS.md Commands for running H3 tests using Vitest. Includes options for single file, directory, watch mode, and a full test suite. ```bash pnpm vitest run test/body.test.ts # single file pnpm vitest run test/unit/ # unit tests pnpm dev # watch mode (all) pnpm test # full: lint + typecheck + coverage ``` -------------------------------- ### Register Global Middleware Source: https://github.com/h3js/h3/blob/main/docs/1.guide/900.api/1.h3.md Use the use method to register middleware that executes for incoming requests. ```javascript const app = new H3() .use((event) => { console.log(`request: ${event.req.url}`); }) .all("/", () => "OK"); ``` -------------------------------- ### Validate Request Body with Valibot Source: https://github.com/h3js/h3/blob/main/docs/4.examples/validate-data.md Use `readValidatedBody` with a Valibot schema to validate the request body. If validation fails, H3 throws a 400 error. Ensure Valibot is installed. ```js import { readValidatedBody } from "h3"; import * as v from "valibot"; const userSchema = v.object({ name: v.pipe(v.string(), v.minLength(3), v.maxLength(20)), age: v.pipe(v.number(), v.integer(), v.minValue(0)), }); app.use(async (event) => { const body = await readValidatedBody(event, userSchema); return `Hello ${body.name}! You are ${body.age} years old.`; }); ``` -------------------------------- ### Validate Request Body with Zod Source: https://github.com/h3js/h3/blob/main/docs/4.examples/validate-data.md Use `readValidatedBody` with a Zod schema to validate the request body. If validation fails, H3 throws a 400 error. Ensure Zod is installed. ```js import { readValidatedBody } from "h3"; import { z } from "zod"; const userSchema = z.object({ name: z.string().min(3).max(20), age: z.number({ coerce: true }).positive().int(), }); app.use(async (event) => { const body = await readValidatedBody(event, userSchema); return `Hello ${body.name}! You are ${body.age} years old.`; }); ``` -------------------------------- ### Register Global Middleware Source: https://github.com/h3js/h3/blob/main/docs/1.guide/1.basics/3.middleware.md Use `app.use()` to register middleware that runs on every request before route handlers. This is useful for logging or general request processing. ```javascript app.use((event) => { console.log(event); }); ``` -------------------------------- ### H3.config Property Source: https://github.com/h3js/h3/blob/main/docs/1.guide/900.api/1.h3.md Provides access to the global H3 instance configuration. ```APIDOC ## H3.config Property ### Description Global H3 instance config. ### Usage ```js // Accessing the configuration // console.log(app.config.debug); ``` ``` -------------------------------- ### H3.use Method Source: https://github.com/h3js/h3/blob/main/docs/1.guide/900.api/1.h3.md Registers a global middleware function that will be executed for every request. ```APIDOC ## H3.use Method ### Description Register a global [middleware](/guide/basics/middleware). ### Request Example ```js const app = new H3() .use((event) => { console.log(`request: ${event.req.url}`); }) .all("/", () => "OK"); ``` ``` -------------------------------- ### Creating H3 Plugins Source: https://github.com/h3js/h3/blob/main/docs/1.guide/901.advanced/1.plugins.md Plugins are functions that accept an H3 instance to apply logic. The definePlugin utility provides a typed factory function for creating plugins. ```js app.register((app) => { app.use(...) }) ``` ```js import { definePlugin } from "h3"; const logger = definePlugin((h3, _options) => { if (h3.config.debug) { h3.use((req) => { console.log(`[${req.method}] ${req.url}`); }); } }); ``` -------------------------------- ### Proxy Incoming Request with Body Streaming Source: https://github.com/h3js/h3/blob/main/docs/2.utils/5.proxy.md Use `proxyRequest` to proxy an incoming request to a target URL, streaming the request body without buffering. Internal requests starting with '/' are handled via `event.app.fetch()`. ```typescript proxyRequest(event, target, opts) ``` -------------------------------- ### H3.fetch Method Source: https://github.com/h3js/h3/blob/main/docs/1.guide/900.api/1.h3.md Similar to H3.request but only accepts a single (req: Request) argument for cross-runtime compatibility. ```APIDOC ## H3.fetch Method ### Description Similar to `H3.request` but only accepts one `(req: Request)` argument for cross runtime compatibility. ### Request Example ```ts const response = await app.fetch(new Request("/")); ``` ``` -------------------------------- ### Registering multiple methods for a single route Source: https://github.com/h3js/h3/blob/main/docs/1.guide/1.basics/2.routing.md Chain multiple HTTP methods to the same route path. ```js app .get("/hello", () => "GET Hello world!") .post("/hello", () => "POST Hello world!") .all("/hello", () => "Any other method!"); ``` -------------------------------- ### Authentication Utilities Source: https://github.com/h3js/h3/blob/main/docs/2.utils/4.security.md Utilities for implementing basic authentication in H3 applications. ```APIDOC ## basicAuth(opts) ### Description Create a basic authentication middleware. ### Parameters - **opts** (object) - Required - Configuration options including password. ### Request Example ```ts import { H3, serve, basicAuth } from "h3"; const auth = basicAuth({ password: "test" }); app.get("/", (event) => `Hello ${event.context.basicAuth?.username}!`, [auth]); ``` ## requireBasicAuth(event, opts) ### Description Apply basic authentication for current request. ### Parameters - **event** (object) - Required - The H3 event object. - **opts** (object) - Required - Configuration options including password. ``` -------------------------------- ### Defining dynamic route parameters Source: https://github.com/h3js/h3/blob/main/docs/1.guide/1.basics/2.routing.md Use the colon prefix to define named parameters accessible via event.context.params. ```js // [GET] /hello/Bob => "Hello, Bob!" app.get("/hello/:name", (event) => { return `Hello, ${event.context.params.name}!`; }); ``` -------------------------------- ### Registering H3 Plugins Source: https://github.com/h3js/h3/blob/main/docs/1.guide/901.advanced/1.plugins.md Plugins can be registered during H3 instance creation or by using the register method. ```js import { H3 } from "h3"; import { logger } from "./logger.mjs"; // Using instance config const app = new H3({ plugins: [logger()], }); // Or register later app.register(logger()); // ... rest of the code.. app.get("/**", () => "Hello, World!"); ``` -------------------------------- ### Matching multi-level sub-routes with wildcards Source: https://github.com/h3js/h3/blob/main/docs/1.guide/1.basics/2.routing.md Use the double asterisk prefix to match multiple levels of sub-routes, with the content stored in the _ parameter. ```js app.get("/hello/**", (event) => `Hello ${event.context.params._}!`); ``` -------------------------------- ### Fetch App Routes Source: https://github.com/h3js/h3/blob/main/docs/1.guide/900.api/1.h3.md Use the request method to perform fetch-compatible requests against the application routes. ```typescript const response = await app.request("/"); console.log(response, await response.text()); ``` -------------------------------- ### Writing Cross-Runtime Tests with H3 Source: https://github.com/h3js/h3/blob/main/AGENTS.md Use `describeMatrix` for tests that need to run across different JavaScript runtimes. `ctx.app` provides a fresh H3 instance, and `ctx.fetch` handles URL resolution. Unhandled errors are tracked in `ctx.errors`. ```typescript import { describeMatrix } from "./_setup.ts"; describeMatrix("feature name", (ctx, { it, expect }) => { it("does something", async () => { ctx.app.get("/test", () => "hello"); const res = await ctx.fetch("/test"); expect(await res.text()).toBe("hello"); }); }); ``` -------------------------------- ### Convert Node.js handlers to H3 Source: https://github.com/h3js/h3/blob/main/docs/1.guide/1.basics/4.handler.md Use fromNodeHandler to adapt legacy (req, res) style Node.js handlers for H3. ```js import { H3, fromNodeHandler } from "h3"; // Force using Node.js compatibility (also works with Bun and Deno) import { serve } from "h3/node"; export const app = new H3(); const nodeHandler = (req, res) => { res.end("Node handlers work!"); }; app.get("/web", fromNodeHandler(nodeHandler)); ``` -------------------------------- ### H3.on Method Source: https://github.com/h3js/h3/blob/main/docs/1.guide/900.api/1.h3.md Registers a route handler for a specific HTTP method and path. ```APIDOC ## H3.on Method ### Description Register route handler for specific HTTP method. ### Request Example ```js const app = new H3().on("GET", "/", () => "OK"); ``` ``` -------------------------------- ### Execute handlers via .fetch Source: https://github.com/h3js/h3/blob/main/docs/1.guide/1.basics/4.handler.md Invoke handlers directly using the .fetch method without requiring an H3 instance. ```js const handler = defineHandler(async (event) => `Request: ${event.req.url}`); const response = await handler.fetch("http://localhost/"); console.log(response, await response.text()); ``` -------------------------------- ### Creating and Throwing HTTPError Source: https://github.com/h3js/h3/blob/main/docs/1.guide/1.basics/6.error.md Demonstrates various syntaxes for creating and throwing HTTPError instances, including using messages, details, status codes, and full object configurations. ```javascript import { HTTPError } from "h3"; app.get("/error", (event) => { // Using message and details throw new HTTPError("Invalid user input", { status: 400 }); // Using HTTPError.status(code) throw HTTPError.status(400, "Bad Request"); // Using single object throw new HTTPError({ status: 400, statusText: "Bad Request", message: "Invalid user input", data: { field: "email" }, body: { date: new Date().toJSON() }, headers: {}, }); }); ``` -------------------------------- ### Returning a Web Response Object Source: https://github.com/h3js/h3/blob/main/docs/1.guide/1.basics/5.response.md Returning a native Response object allows full control over the response, though prepared headers will be merged. ```ts app.get("/", (event) => new Response("Hello, world!", { headers: { "x-powered-by": "H3" } })); ``` -------------------------------- ### WebSocket Utilities Source: https://github.com/h3js/h3/blob/main/docs/2.utils/9.more.md Utilities for defining WebSocket hooks and handlers. ```APIDOC ## defineWebSocket(hooks) ### Description Define WebSocket hooks. ## defineWebSocketHandler() ### Description Define WebSocket event handler. ``` -------------------------------- ### H3.request Method Source: https://github.com/h3js/h3/blob/main/docs/1.guide/900.api/1.h3.md A fetch-compatible function to fetch app routes. Accepts relative paths, URLs, or Request objects and returns a Response promise. ```APIDOC ## H3.request Method ### Description A [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)-compatible function allowing to fetch app routes. Input can be a relative path, [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL), or [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request). Returned value is a [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) promise. ### Request Example ```ts const response = await app.request("/"); console.log(response, await response.text()); ``` ``` -------------------------------- ### Create a Stream with Dynamic Content Source: https://github.com/h3js/h3/blob/main/docs/4.examples/stream-response.md Create a ReadableStream that enqueues random numbers at intervals and closes after a delay. This demonstrates dynamic data generation within a stream. ```ts let interval: NodeJS.Timeout; const stream = new ReadableStream({ start(controller) { controller.enqueue("