Static Files

Serve static assets from disk with automatic MIME detection.

Serve static files (HTML, CSS, JS, images, etc.) directly from disk using @miiajs/serve-static.

Basic usage

import { Miia } from '@miiajs/core'
import { serveStatic } from '@miiajs/serve-static'

const app = new Miia().register(AppModule)

serveStatic(app, '/static', './public')

This serves all files from the ./public directory under the /static URL prefix:

GET /static/style.css  ->  ./public/style.css
GET /static/app.js     ->  ./public/app.js
GET /static/logo.png   ->  ./public/logo.png

Options

serveStatic(app, '/assets', './dist', {
  index: 'index.html',  // Index file for directories (default: 'index.html')
  maxAge: 3600,          // Cache-Control max-age in seconds (default: 0)
})
OptionTypeDefaultDescription
indexstring | false'index.html'Index file for directory requests. Set to false to disable.
maxAgenumber0Cache-Control: max-age value in seconds
getMimeType(path: string) => stringbuilt-in mapCustom MIME type resolver

Custom MIME types

Override or extend MIME type detection with a custom getMimeType function:

import { serveStatic, getMimeType } from '@miiajs/serve-static'

serveStatic(app, '/assets', './public', {
  getMimeType: (path) => {
    if (path.endsWith('.glb')) return 'model/gltf-binary'
    if (path.endsWith('.m3u8')) return 'application/vnd.apple.mpegurl'
    return getMimeType(path) // fallback to built-in map
  }
})

The built-in getMimeType function is exported for use as a fallback.

Advanced: raw handler

For custom routing, use createStaticHandler directly:

import { createStaticHandler } from '@miiajs/serve-static'

app.addRoute('GET', '/custom/*', createStaticHandler('./public', { maxAge: 3600 }))

Features

  • Automatic MIME detection for common file types
  • Directory traversal protection — paths outside the root are rejected
  • Index file serving — directory requests serve index.html by default
  • Trailing slash redirect/assets/dir redirects to /assets/dir/
  • Streaming responses — files are streamed, not loaded into memory
  • Cache-Control headers — configurable via maxAge
  • Custom MIME types — plug in any MIME library or extend the built-in map

Supported MIME types

CategoryExtensions
Text.html, .css, .txt, .csv, .xml, .yaml, .yml
JavaScript.js, .mjs, .cjs, .wasm
Data.json, .map, .pdf
Images.svg, .png, .jpg, .jpeg, .gif, .webp, .avif, .ico
Fonts.woff, .woff2, .ttf, .otf, .eot
Audio/Video.mp3, .ogg, .wav, .mp4, .webm
Archives.zip, .gz, .tar

Unknown extensions default to application/octet-stream.