Skip to main content

Overview

The spa middleware serves Single Page Applications by returning the index file for any unmatched routes, enabling client-side routing to work correctly. Use it when you need:
  • React/Vue/Angular app hosting
  • Client-side routing support
  • HTML5 pushState routing

Installation

Quick Start

Configuration

Options

Examples

Basic Usage

From Embedded FS

Skip API Routes

Custom Index

With Prefix

How It Works

  1. Request comes in for /users/123
  2. Check if file exists at ./dist/users/123
  3. If file exists: serve it
  4. If not: serve ./dist/index.html
  5. Client-side router handles /users/123

API Reference

Functions

Complete Example

Technical Details

Implementation Overview

The SPA middleware provides a fallback mechanism for single-page applications by serving the index file when a requested file does not exist. This enables client-side routing to work correctly.

Path Resolution Process

  1. Ignore Path Check: Checks if the request path matches any configured IgnorePaths (default: /api)
  2. Prefix Handling: If a Prefix is configured, strips it from the path before file resolution
  3. File Existence Check: Determines if the requested path corresponds to an actual file:
    • For fs.FS: Uses fs.Stat() to check file existence
    • For directory path: Uses os.Stat() with filepath.Join()
  4. File Serving: If file exists and is not a directory, serves it with appropriate cache headers
  5. Index Fallback: If file doesn’t exist, serves the index file (default: index.html)

Cache Control Strategy

The middleware implements a dual cache control strategy:
  • Static Assets: Configurable via MaxAge option (default: 0/no cache)
    • Sets Cache-Control: public, max-age=<MaxAge> header
    • Recommended: Long cache duration (e.g., 31536000 for 1 year) for versioned assets
  • Index File: Configurable via IndexMaxAge option (default: 0)
    • When IndexMaxAge = 0: Sets Cache-Control: no-cache, no-store, must-revalidate
    • When IndexMaxAge > 0: Sets Cache-Control: public, max-age=<IndexMaxAge>
    • No-cache default ensures users always get latest SPA routing configuration

File Serving Details

The middleware uses http.ServeContent() for file delivery, which provides:
  • Automatic MIME type detection based on file extension
  • HTTP range request support for partial content
  • Proper Last-Modified header handling
  • Efficient byte streaming with io.ReadSeeker

Security Considerations

  • All file paths are cleaned using filepath.Clean() to prevent directory traversal attacks
  • The middleware only serves files from the configured root directory or filesystem
  • Directory listings are disabled (directories trigger index fallback)

Best Practices

  • Define API routes before SPA middleware
  • Use embedded FS for portable deployments
  • Skip API and health check paths
  • Set proper cache headers for static assets
  • Use long cache durations for static assets with content hashing
  • Keep index.html uncached to ensure SPA updates are immediately available

Testing

The SPA middleware includes comprehensive test coverage for all configuration scenarios: