h3
Version:
67 lines (49 loc) • 2.36 kB
Markdown
> Serve static assets such as HTML, images, CSS, JavaScript, etc.
H3 can serve static assets such as HTML, images, CSS, JavaScript, etc.
To serve a static directory, you can use the `serveStatic` utility.
```ts
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 a `Promise` that resolves to the contents of the file or `undefined` if the file does not exist.
- `getMeta` is used to get the metadata of a file. It should return a `Promise` that resolves to the metadata of the file or `undefined` 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.
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:
```ts
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);
```
The `getContents` reads 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.