Nyx by Example

nyx-serve static files

app_static(app, "/assets/", "./public/") serves files from a directory. The runtime auto-detects MIME types for CSS, JS, images, and other common formats.

Code

// nyx-serve static files -- serving CSS, JS, images from a directory

import "std/http"
import "std/web"

fn home(req: Request) -> Response {
    let html: String = "<!DOCTYPE html><html><head><link rel=\"stylesheet\" href=\"/assets/style.css\"></head><body><h1>Home</h1></body></html>"
    return response_html(200, html)
}

fn main() -> int {
    let app: App = app_new()

    // Register dynamic routes first
    app_get(app, "/", home)

    // Static file serving via app_static (from nyx-serve product):
    //   app_static(app, "/assets/", "./public/")
    //
    // When a request path starts with "/assets/", the rest is looked up
    // in ./public/. For example: GET /assets/style.css serves ./public/style.css
    //
    // The serve_app runtime auto-detects MIME types:
    //   .css -> text/css
    //   .js  -> application/javascript
    //   .png -> image/png
    //   .svg -> image/svg+xml

    print("static file serving pattern:")
    print("  app_static(app, \"/assets/\", \"./public/\")")
    print("  GET /assets/style.css -> ./public/style.css")
    print("  GET /assets/app.js    -> ./public/app.js")
    return 0
}

Output

static file serving pattern:
  app_static(app, "/assets/", "./public/")
  GET /assets/style.css -> ./public/style.css
  GET /assets/app.js    -> ./public/app.js

Explanation

app_static(app, url_prefix, fs_root) mounts a filesystem directory under a URL prefix. At request time, nyx-serve strips url_prefix from the path, joins the remainder onto fs_root, and streams the file back with the appropriate Content-Type. Path traversal attempts (.., absolute paths, symlink escapes) are rejected before any filesystem access.

MIME detection is extension-based: .css becomes text/css, .js becomes application/javascript, .png/.jpg/.svg/.webp map to image types, .html to text/html; charset=utf-8. Unknown extensions fall back to application/octet-stream. Register dynamic routes before calling app_static so explicit handlers win over directory lookups.

For a production site, stack app_static behind nyx-proxy to add TLS termination, gzip, and an HTTP cache — the proxy handles the hot path so the backend only regenerates on cache misses.

← Previous Next →

Source: examples/by-example/80-serve-static.nx