Static Assets
h3 can serve static assets such as HTML, images, CSS, JavaScript, etc.
To serve a static directory, you can use the serveStatic
utility.
import { H3, serveStatic } from "h3";
const app = new H3();
app.use("/public/**", (event) => {
return serveStatic(event, {
getContents: (id) => {
// TODO
},
getMeta: (id) => {
// TODO
},
});
});
This does not serve any files yet. You need to implement the getContents
and getMeta
methods.
getContents
is used to read the contents of a file. It should return aPromise
that resolves to the contents of the file orundefined
if the file does not exist.getMeta
is used to get the metadata of a file. It should return aPromise
that resolves to the metadata of the file orundefined
if the file does not exist.
They are separated to allow h3 to respond to HEAD
requests without reading the contents of the file and to use the Last-Modified
header.
Read files
Now, create a index.html
file in the public
directory with a simple message and open your browser to http://localhost:3000. You should see the message.
Then, we can create the getContents
and getMeta
methods:
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,
};
}
},
});
});
await serve(app)
.ready()
.then((s) => console.log(`Server running at ${s.url}`));
The getContents
read the file and returns its contents, pretty simple. The getMeta
uses fs.stat
to get the file metadata. If the file does not exist or is not a file, it returns undefined
. Otherwise, it returns the file size and the last modification time.
The file size and last modification time are used to create an etag to send a 304 Not Modified
response if the file has not been modified since the last request. This is useful to avoid sending the same file multiple times if it has not changed.