or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

directory-listing.mdindex.mdplugin-registration.mdreply-decorators.md
tile.json

plugin-registration.mddocs/

Plugin Registration

Core plugin registration functionality for configuring static file serving with comprehensive options for routing, caching, content delivery, and security.

Capabilities

Main Plugin Function

Registers static file serving capabilities with Fastify, including route creation, reply decorators, and content negotiation.

/**
 * Main static file serving plugin for Fastify
 * @param fastify - Fastify instance to register with
 * @param options - Configuration options for static file serving
 * @returns Promise that resolves when plugin is registered
 */
function fastifyStatic(fastify, options);

Usage Examples:

const fastify = require('fastify')({ logger: true });
const path = require('node:path');

// Basic registration
await fastify.register(require('@fastify/static'), {
  root: path.join(__dirname, 'public')
});

// Advanced registration with multiple options
await fastify.register(require('@fastify/static'), {
  root: [path.join(__dirname, 'public'), path.join(__dirname, 'assets')],
  prefix: '/static/',
  redirect: true,
  wildcard: false,
  preCompressed: true,
  maxAge: '1d',
  setHeaders: (res, path, stat) => {
    res.setHeader('X-Custom-Header', 'value');
  }
});

Plugin Options Interface

Complete configuration interface for all plugin registration options.

/**
 * Send options passed to @fastify/send for file serving behavior
 */
interface SendOptions {
  /** Enable/disable accepting ranged requests */
  acceptRanges?: boolean;
  /** Enable/disable Content-Type header setting */
  contentType?: boolean;
  /** Enable/disable Cache-Control header */
  cacheControl?: boolean;
  /** How to handle dotfiles: 'allow' | 'deny' | 'ignore' */
  dotfiles?: 'allow' | 'deny' | 'ignore';
  /** Enable/disable etag generation */
  etag?: boolean;
  /** File extensions to attempt when no extension in URL */
  extensions?: string[];
  /** Enable immutable directive in Cache-Control */
  immutable?: boolean;
  /** Index file names or false to disable */
  index?: string[] | string | false;
  /** Enable/disable Last-Modified header */
  lastModified?: boolean;
  /** Cache max-age in ms or time string */
  maxAge?: string | number;
}

/**
 * Configuration options for @fastify/static plugin
 */
interface FastifyStaticOptions extends SendOptions {
  /** 
   * Absolute path(s) of directories containing files to serve
   * Can be single path, array of paths, or URL objects
   */
  root: string | string[] | URL | URL[];
  
  /** URL path prefix for virtual mount path (default: '/') */
  prefix?: string;
  
  /** Prevent adding trailing slash to prefix (default: false) */
  prefixAvoidTrailingSlash?: boolean;
  
  /** Enable/disable directory serving (default: true) */
  serve?: boolean;
  
  /** Enable/disable reply decorators (sendFile, download) (default: true) */
  decorateReply?: boolean;
  
  /** Hide schema attribute for registered routes (default: true) */
  schemaHide?: boolean;
  
  /** Function to set custom headers on response */
  setHeaders?: (res: SetHeadersResponse, path: string, stat: Stats) => void;
  
  /** Enable redirection to directories with trailing slash (default: false) */
  redirect?: boolean;
  
  /** Add wildcard route vs pre-scanning files (default: true) */
  wildcard?: boolean;
  
  /** Patterns to ignore when wildcard is false */
  globIgnore?: string[];
  
  /** Function to filter served files based on request */
  allowedPath?: (pathName: string, root: string, request: FastifyRequest) => boolean;
  
  /** Enable serving pre-compressed files (br, gzip) (default: false) */
  preCompressed?: boolean;
  
  /** Enable directory listing functionality */
  list?: boolean | ListOptionsJsonFormat | ListOptionsHtmlFormat;
  
  /** Route constraints for registered routes */
  constraints?: RouteOptions['constraints'];
  
  /** Log level for registered routes */
  logLevel?: RouteOptions['logLevel'];
}

Root Path Configuration

Configure single or multiple root directories for static file serving.

/**
 * Root path configuration - supports multiple formats
 */
type RootPath = string | string[] | URL | URL[];

Usage Examples:

// Single string path
{
  root: path.join(__dirname, 'public')
}

// Multiple paths (first-found, first-served)
{
  root: [
    path.join(__dirname, 'public'),
    path.join(__dirname, 'assets'),
    path.join(__dirname, 'uploads')
  ]
}

// URL object
{
  root: new URL('./public', import.meta.url)
}

// Array of URL objects
{
  root: [
    new URL('./public', import.meta.url),
    new URL('./assets', import.meta.url)
  ]
}

Custom Headers Function

Configure custom header setting for served files.

/**
 * Custom headers function interface
 * @param res - Response object with header methods
 * @param path - Path of the file being served
 * @param stat - File stats object
 */
type SetHeaders = (res: SetHeadersResponse, path: string, stat: Stats) => void;

interface SetHeadersResponse {
  getHeader: FastifyReply['getHeader'];
  setHeader: FastifyReply['header'];
  readonly filename: string;
  statusCode: number;
}

Usage Examples:

{
  setHeaders: (res, path, stat) => {
    // Set custom caching for specific file types
    if (path.endsWith('.css') || path.endsWith('.js')) {
      res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
    }
    
    // Add security headers
    res.setHeader('X-Content-Type-Options', 'nosniff');
    
    // Custom headers based on file stats
    if (stat.size > 1000000) { // Files > 1MB
      res.setHeader('X-Large-File', 'true');
    }
  }
}

Path Filtering Function

Control which files can be served based on request context.

/**
 * Path filtering function for security and access control
 * @param pathName - Requested path name
 * @param root - Root directory path
 * @param request - Fastify request object
 * @returns true to serve file, false to return 404
 */
type AllowedPath = (pathName: string, root: string, request: FastifyRequest) => boolean;

Usage Examples:

{
  allowedPath: (pathName, root, request) => {
    // Block access to sensitive files
    if (pathName.includes('.env') || pathName.includes('config')) {
      return false;
    }
    
    // Restrict based on user authentication
    if (pathName.startsWith('/admin/') && !request.user?.isAdmin) {
      return false;
    }
    
    // Allow access to public files
    return true;
  }
}

Pre-compressed File Support

Configure serving of pre-compressed files with automatic content negotiation.

/**
 * Pre-compressed file support configuration
 */
interface PreCompressedOptions {
  /** Enable serving pre-compressed files with automatic content negotiation */
  preCompressed?: boolean;
}

Usage Examples:

// Enable pre-compressed file support
await fastify.register(require('@fastify/static'), {
  root: path.join(__dirname, 'public'),
  preCompressed: true
});

// Pre-compressed files are automatically served when available:
// Request: GET /style.css
// If client accepts gzip and style.css.gz exists, serves style.css.gz
// If client accepts brotli and style.css.br exists, serves style.css.br
// Otherwise serves style.css

// Supported compression formats (in order of preference):
// - Brotli (.br extension)
// - Gzip (.gz extension) 
// - Deflate

Glob Ignore Patterns

Configure patterns to ignore when using wildcard: false mode.

/**
 * Glob ignore patterns configuration
 */
interface GlobIgnoreOptions {
  /** Patterns to ignore when wildcard is false - uses glob syntax */
  globIgnore?: string[];
}

Usage Examples:

// Ignore specific file patterns when pre-scanning directories
await fastify.register(require('@fastify/static'), {
  root: path.join(__dirname, 'public'),
  wildcard: false, // Must be false to use globIgnore
  globIgnore: [
    '**/*.tmp',        // Ignore all .tmp files
    '**/.DS_Store',    // Ignore macOS metadata files
    '**/node_modules/**', // Ignore nested dependencies
    '**/*.log',        // Ignore log files
    'private/**'       // Ignore entire private directory
  ]
});

// Without globIgnore, all files in the root directory are served
// With globIgnore, matching patterns are excluded from route generation

Constraint Configuration

Configure route constraints for registered static routes.

/**
 * Route constraints configuration
 */
interface RouteConstraints {
  host?: string | RegExp | string[];
  version?: string;
  [key: string]: any;
}

Usage Examples:

// Host constraints
{
  constraints: {
    host: 'cdn.example.com'
  }
}

// Multiple host constraints
{
  constraints: {
    host: ['assets.example.com', 'cdn.example.com']
  }
}

// Version constraints
{
  constraints: {
    version: '1.0.0'
  }
}