serve-handler

repository·main·Indexed 20 days ago

https://github.com/vercel/serve-handler

A core routing and response engine for HTTP servers that handles file serving, directory listings, and routing rules such as rewrites and redirects. It supports configuration for clean URLs, custom headers, trailing slashes, and ETag generation, and allows for the extension of internal file system and response methods via custom middleware.

Tokens
3.2K
Snippets
14
Records
21
Agent score
20%

What's inside serve-handler

  1. Configure `directoryListing` and `unlisted`

    main

    Directory Listing

    When a path is a directory, serve-handler can render a file list.

    • Set directoryListing: false to disable it globally.
    • Use an array of minimatch globs to enable/disable it for specific paths.

    Unlisted

    To hide specific files or directories from the directory listing, add them to the unlisted array using minimatch globs.

    {
      "directoryListing": [
        "/assets/**",
        "/!assets/private"
      ],
      "unlisted": [
        ".DS_Store",
        ".git"
      ]
    }
  2. Customize error templates

    main
    The handler automatically determines the correct error format (e.g., JSON) based on the request. You can provide custom HTML templates for specific status codes by adding a <status-code>.html file to your root directory (e.g., 404.html, 500.html).
  3. Configure directory listing and single file rendering

    main

    By default, serve-handler does not list directory contents. You can enable this via directoryListing.

    • directoryListing: true: Enables directory indexes.
    • directoryListing: ['/docs']: Enables directory indexes only for specific paths.
    • renderSingle: true: If a directory contains only one file, serve-handler will serve that file directly instead of the directory listing.
    • unlisted: ['secret-folder']: Prevents specific files or folders from appearing in the directory listing.

    If the client requests application/json via the Accept header, the directory listing will be returned as a JSON object instead of HTML.

  4. Configure `rewrites`

    main

    Use rewrites to serve a different file/path behind the scenes without changing the URL in the browser. This is useful for Single Page Applications (SPAs).

    • Routing Segments: Supports :id style segments (matched via path-to-regexp).
    • Globs: Supports glob patterns (matched via minimatch).
    {
      "rewrites": [
        { "source": "app/**", "destination": "/index.html" },
        { "source": "projects/*/edit", "destination": "/edit-project.html" },
        { "source": "/projects/:id/edit", "destination": "/edit-project-:id.html" }
      ]
    }
  5. Configure `trailingSlash`

    main

    Control how trailing slashes are handled in URLs.

    • true: Forces a trailing slash on all URLs (performs a 301 redirect if missing).
    • false: Removes trailing slashes from all URLs.
    • default: The handler makes assumptions based on the path.
    {
      "trailingSlash": true
    }
  6. Configure `redirects`

    main

    Use redirects to forward requests to different paths or external URLs.

    • Default Status: All redirects use status code 301 by default.
    • Custom Status: Set the type property on the redirect object (e.g., 302).
    • Routing: Supports both minimatch globs and path-to-regexp segments.
    {
      "redirects": [
        { "source": "/from", "destination": "/to" },
        { "source": "/old-docs/:id", "destination": "/new-docs/:id" },
        { "source": "/old", "destination": "/new", "type": 302 }
      ]
    }
  7. Configure `headers`

    main

    Set custom headers (or overwrite existing ones) for specific paths using minimatch globs.

    • Removing Headers: Set a header value to null to remove a previously defined header.
    • ETag Interaction: If you define an ETag header, the handler will automatically respond with 304 if the If-None-Match header matches.
    {
      "headers": [
        {
          "source" : "**/*.@(jpg|jpeg|gif|png)",
          "headers" : [{
            "key" : "Cache-Control",
            "value" : "max-age=7200"
          }]
        }
      ]
    }
  8. Configure the `public` directory

    main

    By default, the current working directory is served. Use the public option to specify an absolute path or a relative path to a specific directory.

    NOTE: The path cannot contain globs or regular expressions.

    {
      "public": "_site"
    }
  9. Configure rewrites and redirects

    main

    You can use rewrites to map a request path to a different file path internally without changing the URL in the browser, and redirects to send the user to a new URL with a specific status code.

    Rewrites

    Rewrites use path-to-regexp patterns. You can use named parameters in the source which are then passed to the destination.

    rewrites: [
      { source: '/blog/:slug', destination: '/posts/:slug.html' }
    ]

    Redirects

    Redirects perform a standard HTTP redirect.

    redirects: [
      { source: '/old-path', destination: '/new-path', type: 301 }
    ]
  10. Configure `cleanUrls`

    main

    When enabled, .html extensions are stripped from paths via a 301 redirect.

    • Boolean: Set to false to disable the feature.
    • Array: Restrict the feature to specific paths using minimatch globs.

    NOTE: Paths can only contain globs matched using minimatch.

    {
      "cleanUrls": false
    }
    {
      "cleanUrls": [
        "/app/**",
        "/!components/**"
      ]
    }
  11. Configure `symlinks` and `etag`

    main

    By default, symlinks are disabled for security and return a 404. Set symlinks: true to resolve them to their targets.

    ETag

    By default, the handler uses Last-Modified. Set etag: true to use a strong ETag response header instead. Note that calculating hashes for large files can be computationally expensive.

    {
      "symlinks": true,
      "etag": true
    }