CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-serve-handler

HTTP request routing and static file serving library that powers the serve package

Pending
Overview
Eval results
Files

configuration.mddocs/

Configuration

Comprehensive configuration system that controls static file serving behavior, URL handling, custom headers, directory listings, and advanced routing patterns.

Capabilities

Configuration Object

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;
}

Public Directory

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'
});

Clean URLs

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/**']
});

URL Rewrites

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'
    }
  ]
});

URL Redirects

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'
    }
  ]
});

Custom Headers

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: '*'
      }]
    }
  ]
});

Directory Listing

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/**']
});

File Exclusion

Excludes files and directories from directory listings.

unlisted?: string[];

Usage Examples:

await handler(req, res, {
  unlisted: [
    '.env',
    '.git',
    'node_modules',
    '*.log',
    'private/**'
  ]
});

Trailing Slash

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
});

Single File Rendering

When a directory contains only one file, serves that file directly instead of showing a directory listing.

renderSingle?: boolean;

Symbolic Links

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
});

ETag Caching

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
});

Complete Configuration Example

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

docs

configuration.md

file-system.md

index.md

request-handling.md

tile.json