Router
Using h3 router allows more advanced and convenient routing system such as parameters and HTTP methods while the app instance itself only allows static prefix matching.
Usage
First, you need to create a router using createRouter
utility and add it to app stack.
import { createApp, createRouter, defineEventHandler } from "h3";
const app = createApp();
const router = createRouter();
app.use(router);
Then, you can register a route to the router using a method where the name is the HTTP method:
router.get(
"/hello",
defineEventHandler((event) => {
return "Hello world!";
}),
);
In this example, we register a route for the GET
method. This means that the event handler will be called only for GET
requests for the /hello
route. If you try to send a POST
or a request to /hello/world
, the event handler will not be called.
use
to register an event handler to the router. It will be called for every HTTP methods.This means that you can register multiple event handlers for the same route with different methods:
router
.get(
"/hello",
defineEventHandler((event) => {
return "GET Hello world!";
}),
)
.post(
"/hello",
defineEventHandler((event) => {
return "POST Hello world!";
}),
);
Route params
You can define parameters in your routes using :
prefix:
router.get(
"/hello/:name",
defineEventHandler((event) => {
return `Hello ${event.context.params.name}!`;
}),
);
In this example, the name
parameter will be available in the event.context.params
object.
If you send a request to /hello/world
, the event handler will return Hello world!
.
Wildcard matcher
Instead of named params, you can use *
for unnamed
router.get(
"/hello/*",
defineEventHandler((event) => {
return `Hello ${event.context.params._}!`;
}),
);
This will match both /hello
and sub routes such as /hello/world
or /hello/123
. But it will only match one level of sub routes.
You can access to the wildcard content using event.context.params._
where _
is a string containing the wildcard content.
If you need to match multiple levels of sub routes, you can use **
prefix:
router.get(
"/hello/**",
defineEventHandler((event) => {
return `Hello ${event.context.params._}!`;
}),
);
This will match /hello
, /hello/world
, /hello/123
, /hello/world/123
, etc.
_
will store the full wildcard content as a single string.Nested Routers
You can nest routers to create a tree of routers. This is useful to split your application into multiple parts like the API and the website.
import { createApp, createRouter, defineEventHandler, useBase } from "h3";
export const app = createApp();
const websiteRouter = createRouter().get(
"/",
defineEventHandler((event) => {
return "Hello world!";
}),
);
const apiRouter = createRouter().get(
"/hello",
defineEventHandler((event) => {
return "Hello API!";
}),
);
websiteRouter.use("/api/**", useBase("/api", apiRouter.handler));
app.use(websiteRouter);
We create two routers. The first one, called websiteRouter
is the main one. The second one, we create a second router called apiRouter
.
Then, we connect the apiRouter
to the websiteRouter
using use
and a wildcard to be sure that every routes starting and HTTP methods with /api
will be handled by the apiRouter
.
.handler
to get the event handler from the router.useBase
is used to add a prefix to each routes of the router. In this example, we add /api
prefix to each routes of the apiRouter
. So, the route /hello
will be /api/hello
.
Finally, we register the websiteRouter
to the app
instance.