Core plugin registration functionality for configuring static file serving with comprehensive options for routing, caching, content delivery, and security.
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');
}
});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'];
}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)
]
}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');
}
}
}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;
}
}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)
// - DeflateConfigure 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 generationConfigure 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'
}
}