App Instance
The core of a h3 server is an app
instance. It is the core of the server that handles incoming requests. You can use app instance to register event handlers.
Initializing an app
You can create a new h3 app instance using createApp
utility:
import { createApp } from "h3";
const app = createApp();
Setting global options
You can pass global app configuration when initializing an app.
Example: Create an app with verbose logging enabled.
const app = createApp({
debug: true,
});
Setting global hooks
When initializing an h3 app, you can register global hooks:
onError
onRequest
onBeforeResponse
onAfterResponse
These hooks are called for every request and can be used to add global logic to your app such as logging, error handling, etc.
const app = createApp({
onError: (error) => {
console.error(error);
},
onRequest: (event) => {
console.log("Request:", event.path);
},
});
Registering event handlers
You can register event handlers to app instance using the app.use
:
import { defineEventHandler } from "h3";
app.use(
"/hello",
defineEventHandler((event) => {
return "Hello world!";
}),
);
This will register the event handler to the app instance and will be called for every request starting with the prefix /hello
. This means that the event handler will be called for /hello
, /hello/world
, /hello/123
, etc.
You can define multiple event handlers for the same route. h3 will try to to call them one by one in order of registration until one of them returns a response. This is called stack runner
.
app.use(
"/",
defineEventHandler((event) => {
return "First";
}),
);
app.use(
"/",
defineEventHandler((event) => {
return "Second";
}),
);
In this example, the first event handler will be called for every request starting with /hello
and the second one will never be called.
However, if you do not return a response from the first event handler, the second one will be called. This is useful to have a middleware pattern.
app.use(
"/",
defineEventHandler((event) => {
console.log("First");
// No response returned
}),
);
app.use(
"/",
defineEventHandler((event) => {
return "Second";
}),
);
If all handlers get called and no response is returned, h3 will end the request with 404 status response.
return
or return undefined
make a 404 Not Found
status response.
Also using return null
will make a 204 No Content
status response.return {}
or return ""
or return true
to make an explicit response.Event handler options
The method use
accepts an optional options
object as third argument:
app.use(
"/hello",
defineEventHandler((event) => {
return "Hello world!";
}),
{
// Options
},
);
matcher
You can define a custom matcher function to have more advanced logic for matching requests but simple than a router.
For example, you can match only odd URLs, /1
, /3
, /5
, etc.:
app.use(
"/",
defineEventHandler((event) => {
return "Odd URLs only";
}),
{
match: (url) => {
return url.substr(1) % 2;
},
},
);
lazy
You can provide an async function that h3 will load on first time a request matching the route is received. It's useful for dynamic imports to reduce startup time.
app.use("/big", () => import("./big-handler"), { lazy: true });
This reduce the startup time because the runtime have less code to load and parse when starting the server.
Internals
h3 app instance has some additional properties. However it is usually not recommended to directly access them unless you know what are you doing!
app.stack
: An ordered array of currently registered event handlers.- Each item has
route
andhandler
properties.
- Each item has
app.options
: Global options object provided when initializing the app.app.handler
: Direct stack handler function (unsafe to directly call).