Static middleware for Fiber serves static files from a specified directory or embedded filesystem. It provides features like directory browsing, file caching, compression, and byte range requests.
Signatures
func New(root string, config ...Config) fiber.Handler
Usage
import (
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/middleware/static"
)
Basic Usage
// Serve files from ./public directory
app.Use("/", static.New("./public"))
// Or using app.Static shorthand
app.Static("/", "./public")
Custom Configuration
app.Use("/assets", static.New("./public", static.Config{
Compress: true,
ByteRange: true,
Browse: false,
MaxAge: 3600,
}))
Embedded Filesystem
import "embed"
//go:embed public/*
var embedFS embed.FS
app.Use("/", static.New("", static.Config{
FS: embedFS,
}))
Multiple Static Directories
app.Static("/css", "./public/stylesheets")
app.Static("/js", "./public/scripts")
app.Static("/images", "./public/img")
Configuration
The file system to serve files from. You can use interfaces compatible with fs.FS like embed.FS, os.DirFS, etc. If not specified, uses the local filesystem.
Next
func(fiber.Ctx) bool
default:"nil"
Defines a function to skip this middleware when it returns true.
ModifyResponse
fiber.Handler
default:"nil"
Defines a function that allows you to alter the response before it’s sent.
NotFoundHandler
fiber.Handler
default:"nil"
Defines a function to handle requests when the file path is not found.
IndexNames
[]string
default:"[\"index.html\"]"
The names of the index files for serving a directory. When a directory is requested, these files are checked in order.
CacheDuration
time.Duration
default:"10 * time.Second"
Expiration duration for inactive file handlers. Use a negative value to disable caching.
The value for the Cache-Control HTTP header that is set on the file response. MaxAge is defined in seconds.
When set to true, the server tries minimizing CPU usage by caching compressed files. This works differently than the compression middleware.
When set to true, enables byte range requests for partial content delivery (useful for video streaming).
When set to true, enables directory browsing and generates directory listings.
When set to true, enables direct download by setting the Content-Disposition header to attachment.
Default Config
var ConfigDefault = Config{
IndexNames: []string{"index.html"},
CacheDuration: 10 * time.Second,
}
Common Use Cases
Serve SPA (Single Page Application)
app.Static("/", "./dist")
// Fallback to index.html for SPA routing
app.Use(func(c fiber.Ctx) error {
return c.SendFile("./dist/index.html")
})
Serve with Browser Caching
app.Use("/static", static.New("./public", static.Config{
MaxAge: 86400, // 1 day in seconds
}))
Enable Compression
app.Use("/assets", static.New("./public", static.Config{
Compress: true,
MaxAge: 86400,
}))
Video Streaming
app.Use("/videos", static.New("./media", static.Config{
ByteRange: true,
MaxAge: 3600,
}))
Directory Browsing
app.Use("/files", static.New("./documents", static.Config{
Browse: true,
}))
File Downloads
app.Use("/downloads", static.New("./files", static.Config{
Download: true,
}))
Embedded Static Files
import "embed"
//go:embed dist/*
var distFS embed.FS
app.Use("/", static.New("", static.Config{
FS: distFS,
}))
Custom 404 Handler
app.Use("/assets", static.New("./public", static.Config{
NotFoundHandler: func(c fiber.Ctx) error {
return c.Status(404).SendString("Asset not found")
},
}))
app.Use("/files", static.New("./public", static.Config{
ModifyResponse: func(c fiber.Ctx) error {
c.Set("X-Served-By", "Fiber Static")
return c.Next()
},
}))
Multiple Index Files
app.Use("/", static.New("./public", static.Config{
IndexNames: []string{"index.html", "index.htm", "default.html"},
}))
Best Practices
Use Path Prefix for Organization
// Good - organized under /static
app.Static("/static", "./public")
// Avoid - serves from root
app.Static("/", "./public")
Enable Caching in Production
if os.Getenv("ENV") == "production" {
app.Static("/assets", "./public", static.Config{
Compress: true,
MaxAge: 86400 * 7, // 1 week
})
} else {
app.Static("/assets", "./public")
}
Secure Directory Browsing
// Only enable in development
app.Use("/files", static.New("./uploads", static.Config{
Browse: os.Getenv("ENV") == "development",
}))
Handle Static Files Before Routes
// Middleware
app.Use(logger.New())
// Static files
app.Static("/public", "./public")
// Routes
app.Get("/api/users", getUsers)
Use Embedded FS in Production
import "embed"
//go:embed dist
var dist embed.FS
if os.Getenv("ENV") == "production" {
app.Use("/", static.New("", static.Config{
FS: dist,
MaxAge: 86400,
}))
} else {
app.Static("/", "./dist")
}
Disable Caching for Development
app.Use("/assets", static.New("./public", static.Config{
CacheDuration: -1, // Disable file caching
}))
Enable Compression for Text Files
// Compress text-based assets (CSS, JS, HTML)
app.Use("/assets", static.New("./public", static.Config{
Compress: true,
}))
Set Appropriate Cache Duration
// Short cache for frequently changing files
app.Static("/", "./dist", static.Config{
CacheDuration: 5 * time.Second,
})
// Long cache for versioned assets
app.Static("/static", "./public", static.Config{
CacheDuration: 1 * time.Hour,
MaxAge: 86400 * 365, // 1 year
})
Use Byte Range for Large Files
// Enable for video, audio, and large downloads
app.Static("/media", "./media", static.Config{
ByteRange: true,
})
Notes
- Files are cached in memory based on
CacheDuration to improve performance
- The
Compress option caches compressed versions of files, not on-the-fly compression
- When using embedded filesystems, the binary includes all files at compile time
- Directory browsing can be a security risk - only enable when necessary
MaxAge: 0 means no browser caching; files are re-validated on each request
- Byte range requests are essential for video streaming and large file downloads