Express.js middleware for serving static files from a directory with configurable caching, security, and file handling options
npx @tessl/cli install tessl/npm-serve-static@2.2.0serve-static provides Express.js middleware for serving static files from a directory. It enables web servers to efficiently serve static assets like HTML, CSS, JavaScript, images, and other files with configurable options for caching, security, and file handling.
npm install serve-staticconst serveStatic = require('serve-static');const express = require('express');
const serveStatic = require('serve-static');
const app = express();
// Basic static file serving
app.use(serveStatic('public'));
// With options
app.use(serveStatic('public', {
index: ['index.html', 'index.htm'],
maxAge: '1d',
dotfiles: 'ignore'
}));
app.listen(3000);Creates a new middleware function to serve files from within a given root directory.
/**
* Create a new middleware function to serve files from within a given root directory
* @param {string} root - Root directory path for serving files (required)
* @param {ServeStaticOptions} options - Configuration options (optional)
* @returns {Function} Express/Connect middleware function
* @throws {TypeError} When root path is missing or not a string
* @throws {TypeError} When setHeaders option is not a function
*/
function serveStatic(root, options);Usage Examples:
// Basic usage
const serve = serveStatic('public/assets');
// With comprehensive options
const serve = serveStatic('public', {
index: ['index.html', 'default.html'],
maxAge: '1 day',
etag: true,
lastModified: true,
dotfiles: 'ignore',
fallthrough: true,
redirect: true,
setHeaders: function(res, path, stat) {
res.setHeader('X-Timestamp', Date.now());
}
});
// Express integration
const express = require('express');
const app = express();
app.use('/static', serve);
// Vanilla Node.js integration
const http = require('http');
const finalhandler = require('finalhandler');
const server = http.createServer(function(req, res) {
serve(req, res, finalhandler(req, res));
});The middleware function returned by serveStatic() handles HTTP requests for static files.
/**
* Express/Connect middleware function for serving static files
* @param {Object} req - HTTP request object
* @param {Object} res - HTTP response object
* @param {Function} next - Next middleware function
*/
function middleware(req, res, next);All options are passed as properties of an options object to the serveStatic() function:
/**
* Enable or disable accepting ranged requests
* @type {boolean}
* @default true
*/
acceptRanges: boolean;/**
* Enable or disable setting Cache-Control response header
* @type {boolean}
* @default true
*/
cacheControl: boolean;/**
* Set how "dotfiles" are treated when encountered
* @type {string}
* @default 'ignore'
* @values 'allow' | 'deny' | 'ignore'
*/
dotfiles: 'allow' | 'deny' | 'ignore';'allow' - No special treatment for dotfiles'deny' - Deny a request for a dotfile and 403/next()'ignore' - Pretend like the dotfile does not exist and 404/next()/**
* Enable or disable etag generation
* @type {boolean}
* @default true
*/
etag: boolean;/**
* Set file extension fallbacks for when files are not found
* @type {string[] | false}
* @default false
* @example ['html', 'htm']
*/
extensions: string[] | false;/**
* Set the middleware to have client errors fall-through as just unhandled requests
* @type {boolean}
* @default true
*/
fallthrough: boolean;/**
* Enable or disable the immutable directive in the Cache-Control response header
* @type {boolean}
* @default false
*/
immutable: boolean;/**
* Directory index file configuration
* @type {string | string[] | false}
* @default 'index.html'
*/
index: string | string[] | false;/**
* Enable or disable Last-Modified header
* @type {boolean}
* @default true
*/
lastModified: boolean;/**
* Provide a max-age in milliseconds for http caching
* @type {number | string}
* @default 0
*/
maxAge: number | string;Also accepts string format compatible with the ms module (e.g., '1d', '2h', '30m').
/**
* Alias for maxAge option
* @type {number | string}
* @default 0
*/
maxage: number | string;/**
* Redirect to trailing "/" when the pathname is a dir
* @type {boolean}
* @default true
*/
redirect: boolean;/**
* Function to set custom headers on response
* @type {Function}
* @param {Object} res - The response object
* @param {string} path - The file path that is being sent
* @param {Object} stat - The stat object of the file that is being sent
*/
setHeaders: (res, path, stat) => void;Usage Example:
const serve = serveStatic('public', {
setHeaders: function(res, path, stat) {
// Set cache headers based on file type
if (path.endsWith('.html')) {
res.setHeader('Cache-Control', 'public, max-age=0');
}
// Add security headers
res.setHeader('X-Content-Type-Options', 'nosniff');
}
});/**
* Configuration options for serve-static middleware
*/
interface ServeStaticOptions {
acceptRanges?: boolean;
cacheControl?: boolean;
dotfiles?: 'allow' | 'deny' | 'ignore';
etag?: boolean;
extensions?: string[] | false;
fallthrough?: boolean;
immutable?: boolean;
index?: string | string[] | false;
lastModified?: boolean;
maxAge?: number | string;
maxage?: number | string;
redirect?: boolean;
setHeaders?: (res: Object, path: string, stat: Object) => void;
}The middleware handles various error conditions based on configuration:
fallthrough is falsenext(err)fallthrough setting
fallthrough is true: calls next() to continue to next middlewarefallthrough is false: calls next(err) to forward the errorconst express = require('express');
const serveStatic = require('serve-static');
const app = express();
// Single directory
app.use(serveStatic('public'));
// Multiple directories with fallback
app.use(serveStatic('public-optimized'));
app.use(serveStatic('public'));
// Mount at specific path
app.use('/assets', serveStatic('public/assets'));
app.listen(3000);const http = require('http');
const finalhandler = require('finalhandler');
const serveStatic = require('serve-static');
const serve = serveStatic('public', {
index: ['index.html', 'index.htm']
});
const server = http.createServer(function(req, res) {
serve(req, res, finalhandler(req, res));
});
server.listen(3000);const contentDisposition = require('content-disposition');
const serveStatic = require('serve-static');
const serve = serveStatic('public/downloads', {
index: false,
setHeaders: function(res, path) {
res.setHeader('Content-Disposition', contentDisposition(path));
}
});