> ## Documentation Index
> Fetch the complete documentation index at: https://docs.go-mizu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Embed

> Embedded filesystem middleware for serving bundled assets.

## Overview

The `embed` middleware provides helpers for serving files from Go's embedded filesystem (embed.FS), enabling single-binary deployments.

Use it when you need:

* Single binary deployment
* Bundled static assets
* Embedded templates

## Installation

```go theme={null}
import "github.com/go-mizu/mizu/middlewares/embed"
```

## Quick Start

```go theme={null}
//go:embed static/*
var staticFS embed.FS

app := mizu.New()
app.Use(embed.Static(staticFS, "static"))
```

## Examples

### Serve Static Files

```go theme={null}
//go:embed static/*
var staticFS embed.FS

app.Use(embed.Static(staticFS, "static"))
// Files at static/css/app.css available at /css/app.css
```

### With Prefix

```go theme={null}
//go:embed assets/*
var assetsFS embed.FS

app.Use(embed.WithOptions(embed.Options{
    FS:     assetsFS,
    Root:   "assets",
    Prefix: "/assets",
}))
// /assets/js/app.js -> assets/js/app.js
```

### Multiple Embeds

```go theme={null}
//go:embed static/*
var staticFS embed.FS

//go:embed templates/*
var templatesFS embed.FS

// Serve static files
app.Use(embed.Static(staticFS, "static"))

// Load templates
tmpl := embed.MustParseTemplates(templatesFS, "templates/*.html")
```

### SPA with Embed

```go theme={null}
//go:embed dist/*
var distFS embed.FS

app.Use(embed.SPA(distFS, "dist"))
```

## API Reference

### Functions

```go theme={null}
// Static serves embedded static files
func Static(fs embed.FS, root string) mizu.Middleware

// SPA serves embedded SPA
func SPA(fs embed.FS, root string) mizu.Middleware

// WithOptions creates with configuration
func WithOptions(opts Options) mizu.Middleware

// Helper functions
func MustParseTemplates(fs embed.FS, pattern string) *template.Template
func ReadFile(fs embed.FS, name string) ([]byte, error)
```

## Build Considerations

```go theme={null}
// Embed entire directory
//go:embed static/*

// Embed specific files
//go:embed favicon.ico robots.txt

// Embed with pattern
//go:embed templates/*.html templates/**/*.html
```

## Technical Details

### Implementation Overview

The embed middleware provides a bridge between Go's `embed.FS` and Mizu's HTTP serving capabilities. It wraps the standard library's `http.FileServer` with additional features like custom root directories, caching headers, and SPA routing.

### Core Components

**Filesystem Handling**

* Uses `fs.FS` interface for maximum flexibility
* Supports `fs.Sub` to create subdirectory filesystems
* Falls back to original filesystem if subdirectory doesn't exist
* Implements proper path cleaning and normalization

**File Serving Strategy**

1. Cleans and normalizes the request path
2. Attempts to open the requested file
3. Falls back to index file for directory requests
4. Delegates to `NotFoundHandler` or next middleware if file not found
5. Uses `http.FileServer` for actual serving (handles range requests, content-type, etc.)

**Cache Control**

* Optional `MaxAge` setting for Cache-Control headers
* Custom `itoa` function to avoid allocations for header values
* Headers set before delegating to file server

**SPA Support**

* Custom `NotFoundHandler` that serves index.html for missing routes
* Preserves normal file serving for actual assets
* Uses `http.ServeContent` for proper handling of conditional requests

### Handler vs Middleware

The package provides both middleware and handler functions:

* **Middleware** (`New`, `WithOptions`, `Static`, etc.): Falls through to next handler if file not found
* **Handler** (`Handler`, `HandlerWithOptions`): Directly serves files without fallthrough

## Best Practices

* Use for production deployments
* Keep embedded files small
* Use content hashing for cache busting
* Test embedded files in CI

## Testing

The embed middleware includes comprehensive test coverage for all functionality:

| Test Case                                 | Description                           | Expected Behavior                                               |
| ----------------------------------------- | ------------------------------------- | --------------------------------------------------------------- |
| `TestNew`                                 | Basic middleware creation and serving | Serves root index.html and nested files successfully            |
| `TestWithOptions_Root`                    | Serving from a subdirectory           | Files from subdirectory accessible at root URL path             |
| `TestWithOptions_MaxAge`                  | Cache control headers                 | Cache-Control header set to specified max-age value             |
| `TestWithOptions_NotFoundHandler`         | Custom not found handling             | Custom handler invoked for missing files with JSON response     |
| `TestHandler`                             | Direct handler (non-middleware)       | Serves files without middleware chain                           |
| `TestStatic`                              | Static helper function                | Serves files from specified subdirectory                        |
| `TestWithCaching`                         | Caching helper function               | Cache-Control header set correctly                              |
| `TestIndexFile`                           | Index file serving                    | Root and subdirectory index files served automatically          |
| `TestFallthrough`                         | Middleware fallthrough                | Non-existent files fall through to next handler                 |
| `TestSPA`                                 | Single-page application mode          | Existing files served normally, unknown routes serve index.html |
| `TestSPA_DefaultIndex`                    | SPA with default index                | Empty index parameter defaults to "index.html"                  |
| `TestHandlerWithOptions`                  | Handler with options                  | Options applied correctly in handler mode                       |
| `TestHandlerWithOptions_Root`             | Handler with custom root              | Files served from specified root directory                      |
| `TestWithOptions_InvalidRoot`             | Invalid root directory handling       | Falls back to original filesystem when root doesn't exist       |
| `TestWithOptions_PathWithoutLeadingSlash` | Path normalization                    | Paths without leading slash handled correctly                   |
| `TestItoa`                                | Integer to string conversion          | Custom itoa function converts integers correctly                |

## Related Middlewares

* [static](/middlewares/static) - File system static files
* [spa](/middlewares/spa) - SPA support
* [favicon](/middlewares/favicon) - Favicon serving
