Skip to main content
Version: Next

Static

The Static middleware serves assets such as images, CSS, and JavaScript.

info

By default, it serves index.html when a directory is requested. Customize this behavior in the Config options.

Signatures​

func New(root string, cfg ...Config) fiber.Handler

Examples​

Import the package:

import(
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/middleware/static"
)

Serving files from a directory​

app.Get("/*", static.New("./public"))
Test
curl http://localhost:3000/hello.html
curl http://localhost:3000/css/style.css

Serving files from a directory with Use​

app.Use("/", static.New("./public"))
Test
curl http://localhost:3000/hello.html
curl http://localhost:3000/css/style.css

Serving a single file​

app.Use("/static", static.New("./public/hello.html"))
Test
curl http://localhost:3000/static # will show hello.html
curl http://localhost:3000/static/john/doe # will show hello.html

Serving files using os.DirFS​

app.Get("/files*", static.New("", static.Config{
FS: os.DirFS("files"),
Browse: true,
}))
Test
curl http://localhost:3000/files/css/style.css
curl http://localhost:3000/files/index.html

Serving files using embed.FS​

//go:embed path/to/files
var myfiles embed.FS

app.Get("/files*", static.New("", static.Config{
FS: myfiles,
Browse: true,
}))
Test
curl http://localhost:3000/files/css/style.css
curl http://localhost:3000/files/index.html

SPA (Single Page Application)​

app.Use("/web", static.New("", static.Config{
FS: os.DirFS("dist"),
}))

app.Get("/web*", func(c fiber.Ctx) error {
return c.SendFile("dist/index.html")
})
Test
curl http://localhost:3000/web/css/style.css
curl http://localhost:3000/web/index.html
curl http://localhost:3000/web
caution

To define static routes using Get, append the wildcard (*) operator at the end of the route.

info

The file server resolves the path the router matched. Fiber normalizes request paths before routing (see Path normalization), so middleware mounted on /static/private also guards /static/%70rivate/secret.txt and /static/x/../private/secret.txt.

Escapes the router leaves encoded, such as %20, %40 or %25, are decoded once to obtain the file name: /static/hello%20world.txt serves hello world.txt and /static/100%25.txt serves 100%.txt. A path that cannot name a file inside the root is answered with 404 Not Found: an escape that would produce a slash, a backslash or a control character, a malformed escape such as %zz, and an empty, . or .. segment. So /static/private%2Fsecret.txt never reaches private/secret.txt unless UnescapePath decodes it for the router as well, and /static//private/secret.txt is not found. With UnescapePath enabled the router has already decoded every escape, so the file server decodes nothing and a malformed escape is an ordinary part of the name: /static/100%zz.txt and /static/100%25zz.txt both name 100%zz.txt. A percent sign that remains after that single decoding is an ordinary character, as RFC 3986 requires, so /static/%2570rivate/secret.txt looks for a directory literally named %70rivate and never reaches private.

Config​

PropertyTypeDescriptionDefault
Nextfunc(fiber.Ctx) boolNext defines a function to skip this middleware when it returns true.nil
FSfs.FSFS is the file system to serve the static files from.

You can use interfaces compatible with fs.FS like embed.FS, os.DirFS etc.
nil
CompressboolWhen set to true, the server tries minimizing CPU usage by caching compressed files. The middleware will compress the response using gzip, brotli, or zstd compression depending on the Accept-Encoding header.

This works differently than the github.com/gofiber/compression middleware.
false
ByteRangeboolWhen set to true, enables byte range requests.false
BrowseboolWhen set to true, enables directory browsing.false
DownloadboolWhen set to true, enables direct download.false
IndexNames[]stringThe names of the index files for serving a directory.[]string{"index.html"}
CacheDurationtime.DurationExpiration duration for inactive file handlers.

Use a negative time.Duration to disable it.
10 * time.Second
MaxAgeintThe value for the Cache-Control HTTP-header that is set on the file response. MaxAge is defined in seconds.0
ModifyResponsefiber.HandlerModifyResponse defines a function that allows you to alter the response.nil
NotFoundHandlerfiber.HandlerNotFoundHandler defines a function to handle when the path is not found.nil

When Download is enabled, the response of a served file includes a Content-Disposition header with the requested filename, while the Content-Type the file server detected is kept. Non-ASCII names use the filename* parameter as defined by RFC 6266 and RFC 8187. A request for a missing file falls through to the next handler without the header.

MaxAge only applies to successful responses; an error such as 416 Range Not Satisfiable carries no Cache-Control. A handler registered on several routes serves each under that route's own prefix.

info

You can set CacheDuration config property to -1 to disable caching.

Default Config​

var ConfigDefault = Config{
IndexNames: []string{"index.html"},
CacheDuration: 10 * time.Second,
}