Routing

Each request is matched to one (most specific) route handler.

Adding Routes

You can register route handlers to H3 instance using H3.on, H3.[method], or H3.all.

Router is powered by 🌳 Rou3, an ultra-fast and tiny route matcher engine.

Example: Register a route to match requests to the /hello endpoint with HTTP GET method.

  • Using H3.[method]
    app.get("/hello", () => "Hello world!");
    
  • Using H3.on
    app.on("GET", "/hello", () => "Hello world!");
    

You can register multiple event handlers for the same route with different methods:

app
  .get("/hello", () => "GET Hello world!")
  .post("/hello", () => "POST Hello world!")
  .any("/hello", () => "Any other method!");

You can also use H3.all method to register a route accepting any HTTP method:

app.all("/hello", (event) => `This is a ${event.req.method} request!`);

Dynamic Routes

You can define dynamic route parameters using : prefix:

// [GET] /hello/Bob => "Hello, Bob!"
app.get("/hello/:name", (event) => {
  return `Hello, ${event.context.params.name}!`;
});

Instead of named parameters, you can use * for unnamed optional parameters:

app.get("/hello/*", (event) => `Hello!`);

Wildcard Routes

Adding /hello/:name route will match /hello/world or /hello/123. But it will not match /hello/foo/bar. When you need to match multiple levels of sub routes, you can use ** prefix:

app.get("/hello/**", (event) => `Hello ${event.context.params._}!`);

This will match /hello, /hello/world, /hello/123, /hello/world/123, etc.

Param _ will store the full wildcard content as a single string.

Route Meta

You can define optional route meta when registering them, accessible from any middleware.

import { H3 } from "h3";

const app = new H3();

app.use((event) => {
  console.log(event.context.matchedRoute?.meta); // { auth: true }
});

app.get("/", (event) => "Hi!", { meta: { auth: true } });
It is also possible to add route meta when defining them using defineHandler object syntax.