Static Files
Serve static assets -- HTML, CSS, JavaScript, images -- directly from a directory on disk, with configurable URL prefixes and cache control.
Overview
Most web applications need to serve at least a few static files: a favicon, a CSS stylesheet, client-side JavaScript, or documentation pages. Zigmund provides zigmund.mountStaticFiles to map a URL prefix to a directory, so the framework serves files directly without requiring a separate web server or CDN during development.
Static file serving is intentionally simple. For production deployments with heavy static traffic, consider placing a reverse proxy (nginx, Caddy) or CDN in front of Zigmund and using this feature only for development or low-traffic scenarios.
Example
const std = @import("std");
const zigmund = @import("zigmund");
fn readStaticInfo(req: *zigmund.Request, allocator: std.mem.Allocator) !zigmund.Response {
_ = req;
return zigmund.Response.json(allocator, .{
.static_prefix = "/tutorial/static-files/assets",
.example_file = "/tutorial/static-files/assets/index.html",
});
}
pub fn buildExample(app: *zigmund.App) !void {
try zigmund.mountStaticFiles(
app,
"/tutorial/static-files/assets",
"examples/parity/assets/static",
.{
.include_in_schema = true,
.cache_control = "public, max-age=300",
},
);
try app.get("/tutorial/static-files", readStaticInfo, .{
.summary = "Static files mount example",
.tags = &.{ "parity", "tutorial" },
.operation_id = "tutorial_static_files_info",
});
}
How It Works
-
Call
mountStaticFiles. The function takes four arguments: -app-- The application instance. - URL prefix ("/tutorial/static-files/assets") -- All requests under this path are matched against the directory. - Directory path ("examples/parity/assets/static") -- The filesystem directory containing your static files. Relative paths are resolved from the working directory. - Options struct -- Controls caching and OpenAPI visibility. -
URL-to-file mapping. A request to
/tutorial/static-files/assets/index.htmlmaps to the fileexamples/parity/assets/static/index.html. Subdirectories are traversed automatically, so/assets/css/style.cssmaps tostatic/css/style.css. -
Cache control.
.cache_control = "public, max-age=300"sets theCache-Controlresponse header on every static file response. This tells browsers and proxies to cache files for 300 seconds (5 minutes). Adjust this value for your deployment scenario. -
OpenAPI visibility.
.include_in_schema = trueadds the static file routes to the generated OpenAPI specification. Set this tofalse(the default) if you do not want static asset paths cluttering your API documentation. -
Combine with regular routes. The
/tutorial/static-filesroute is a normal handler that returns JSON. It coexists with the static mount, demonstrating that static files and dynamic endpoints live under the same application.
Key Points
- Zigmund determines the MIME type from the file extension (
.htmlbecomestext/html,.cssbecomestext/css, etc.). Unknown extensions default toapplication/octet-stream. - Path traversal attacks (e.g.,
/../../../etc/passwd) are prevented by the framework. Requests that resolve outside the configured directory receive a404 Not Found. - The directory path is validated at startup. If it does not exist or is not readable,
mountStaticFilesreturns an error. - Static file serving does not support directory listings. Requesting a directory path without a filename returns
404unless anindex.htmlfile is present (behavior depends on framework configuration). - For single-page applications, you may want to combine
mountStaticFileswith a catch-all route that servesindex.htmlfor unmatched paths.
See Also
- First Steps -- Basic application setup and route registration.
- Custom Index Page -- Replace the default root page with a custom handler or static file.
- Middleware -- Add headers or logging to all responses, including static files.
- CORS -- Configure cross-origin access for static assets consumed by browser clients.