HTTP request routing and static file serving library that powers the serve package
—
Comprehensive configuration system that controls static file serving behavior, URL handling, custom headers, directory listings, and advanced routing patterns.
The main configuration object that controls all aspects of the server behavior.
interface Config {
/** Directory path to serve files from (default: current working directory) */
public?: string;
/** Enable clean URLs by stripping .html extensions */
cleanUrls?: boolean | string[];
/** URL rewrite rules */
rewrites?: RewriteRule[];
/** URL redirect rules */
redirects?: RedirectRule[];
/** Custom header rules */
headers?: HeaderRule[];
/** Enable/configure directory listing */
directoryListing?: boolean | string[];
/** Files/patterns to exclude from directory listings */
unlisted?: string[];
/** Force trailing slash behavior on URLs */
trailingSlash?: boolean;
/** Render single file in directory instead of listing */
renderSingle?: boolean;
/** Follow symbolic links (default: false) */
symlinks?: boolean;
/** Use ETag headers instead of Last-Modified */
etag?: boolean;
}Sets the root directory for serving files.
public?: string;Usage Examples:
// Serve from a subdirectory
await handler(req, res, {
public: './dist'
});
// Serve from absolute path
await handler(req, res, {
public: '/var/www/html'
});
// Serve Jekyll site
await handler(req, res, {
public: '_site'
});Enables clean URLs by automatically stripping .html extensions and performing redirects.
cleanUrls?: boolean | string[];Usage Examples:
// Enable for all HTML files
await handler(req, res, {
cleanUrls: true
});
// Disable clean URLs
await handler(req, res, {
cleanUrls: false
});
// Enable only for specific paths
await handler(req, res, {
cleanUrls: ['/blog/**', '/docs/**']
});Transforms incoming request paths to different file system paths before serving.
interface RewriteRule {
/** Source pattern using glob syntax or path-to-regexp patterns */
source: string;
/** Target path or URL, can include captured parameters */
destination: string;
}
rewrites?: RewriteRule[];Usage Examples:
await handler(req, res, {
rewrites: [
// API routes to specific files
{
source: '/api/**',
destination: '/api.html'
},
// Dynamic routes with parameters
{
source: '/user/:id',
destination: '/user.html?id=:id'
},
// Glob pattern matching
{
source: '/old-path/**',
destination: '/new-path/$1'
}
]
});Sends HTTP redirects to different paths or external URLs.
interface RedirectRule {
/** Source pattern using glob syntax or path-to-regexp patterns */
source: string;
/** Target path or URL, can include captured parameters */
destination: string;
/** HTTP status code (default: 301) */
type?: number;
}
redirects?: RedirectRule[];Usage Examples:
await handler(req, res, {
redirects: [
// Permanent redirect
{
source: '/old-page',
destination: '/new-page',
type: 301
},
// Temporary redirect
{
source: '/maintenance',
destination: '/temp-page',
type: 302
},
// External redirect
{
source: '/external',
destination: 'https://example.com'
},
// Pattern-based redirect
{
source: '/blog/:slug',
destination: '/posts/:slug'
}
]
});Applies custom HTTP headers based on path patterns.
interface HeaderRule {
/** Source pattern using glob syntax */
source: string;
/** Headers to apply */
headers: Array<{
key: string;
value: string;
}>;
}
headers?: HeaderRule[];Usage Examples:
await handler(req, res, {
headers: [
// Cache static assets
{
source: '**/*.{js,css,png,jpg,gif}',
headers: [{
key: 'Cache-Control',
value: 'max-age=31536000'
}]
},
// Security headers for HTML
{
source: '**/*.html',
headers: [
{
key: 'X-Frame-Options',
value: 'DENY'
},
{
key: 'X-Content-Type-Options',
value: 'nosniff'
}
]
},
// CORS headers for API
{
source: '/api/**',
headers: [{
key: 'Access-Control-Allow-Origin',
value: '*'
}]
}
]
});Controls directory listing behavior and appearance.
directoryListing?: boolean | string[];Usage Examples:
// Enable directory listing for all directories
await handler(req, res, {
directoryListing: true
});
// Disable directory listing
await handler(req, res, {
directoryListing: false
});
// Enable only for specific paths
await handler(req, res, {
directoryListing: ['/public/**', '/uploads/**']
});Excludes files and directories from directory listings.
unlisted?: string[];Usage Examples:
await handler(req, res, {
unlisted: [
'.env',
'.git',
'node_modules',
'*.log',
'private/**'
]
});Forces consistent trailing slash behavior on URLs.
trailingSlash?: boolean;Usage Examples:
// Force trailing slashes
await handler(req, res, {
trailingSlash: true
});
// Remove trailing slashes
await handler(req, res, {
trailingSlash: false
});When a directory contains only one file, serves that file directly instead of showing a directory listing.
renderSingle?: boolean;Controls whether symbolic links are followed or result in 404 errors.
symlinks?: boolean;Usage Examples:
// Follow symbolic links
await handler(req, res, {
symlinks: true
});
// Block symbolic links (default, more secure)
await handler(req, res, {
symlinks: false
});Uses strong ETag headers instead of Last-Modified for better caching control.
etag?: boolean;Usage Examples:
// Enable ETag caching
await handler(req, res, {
etag: true
});
// Use Last-Modified headers (default)
await handler(req, res, {
etag: false
});const handler = require('serve-handler');
const config = {
public: './public',
cleanUrls: true,
trailingSlash: false,
etag: true,
symlinks: false,
renderSingle: true,
rewrites: [
{
source: '/api/**',
destination: '/api/index.html'
}
],
redirects: [
{
source: '/old-path',
destination: '/new-path',
type: 301
}
],
headers: [
{
source: '**/*.{js,css}',
headers: [{
key: 'Cache-Control',
value: 'max-age=31536000'
}]
}
],
directoryListing: ['/uploads/**'],
unlisted: [
'.DS_Store',
'.git',
'node_modules',
'*.log'
]
};
await handler(request, response, config);Install with Tessl CLI
npx tessl i tessl/npm-serve-handler