Static Files
Serve CSS, JavaScript, images, and other static assets from your project's public/ directory. Nimbus uses Go's built-in http.FileServer under the hood, registered as a route on the Chi router.
Project structure
Place your static assets in the public/ directory at the project root:
myapp/
public/
css/
app.css
js/
app.js
images/
logo.png
favicon.ico
views/
main.go
Configuring the file server
Register a wildcard route that serves files from public/. Use http.StripPrefix so the URL path maps correctly to the file system.
import (
"github.com/CodeSyncr/nimbus"
"github.com/go-chi/chi/v5"
)
func main() {
app := nimbus.New()
// Serve /static/* from the public/ directory
fileServer := http.FileServer(http.Dir("public"))
app.Router.Handle("/static/*",
http.StripPrefix("/static/", fileServer),
)
app.Run()
}
With this setup, /static/css/app.css serves the file at public/css/app.css.
Referencing assets in templates
In your .nimbus templates, reference static assets using the path prefix you configured:
<link rel="stylesheet" href="/static/css/app.css">
<script src="/static/js/app.js"></script>
<img src="/static/images/logo.png" alt="Logo">
Setting cache headers
Wrap the file server with a middleware that sets Cache-Control headers for better performance in production.
func cacheControl(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "public, max-age=31536000, immutable")
next.ServeHTTP(w, r)
})
}
fileServer := http.FileServer(http.Dir("public"))
cached := cacheControl(http.StripPrefix("/static/", fileServer))
app.Router.Handle("/static/*", cached)
Serving from the root path
If you prefer serving assets without a prefix (e.g. /css/app.css directly), mount the file server at the root. Be careful with route conflicts — define your API and page routes first.
// Serve files directly from public/ at the root
fileServer := http.FileServer(http.Dir("public"))
app.Router.Handle("/*", fileServer)
Serving a single file
For individual files like favicon.ico or robots.txt, use a dedicated route with http.ServeFile.
app.Router.Get("/favicon.ico", func(c *http.Context) error {
http.ServeFile(c.Response, c.Request, "public/favicon.ico")
return nil
})
app.Router.Get("/robots.txt", func(c *http.Context) error {
http.ServeFile(c.Response, c.Request, "public/robots.txt")
return nil
})
Using embedded files (Go 1.16+)
For single-binary deployments, embed static files at compile time using embed.FS.
import "embed"
//go:embed public/*
var publicFS embed.FS
func main() {
app := nimbus.New()
sub, _ := fs.Sub(publicFS, "public")
fileServer := http.FileServer(http.FS(sub))
app.Router.Handle("/static/*",
http.StripPrefix("/static/", fileServer),
)
app.Run()
}
Tips
- In development, disable caching so changes to CSS/JS are reflected immediately.
- In production, use long
max-agevalues and fingerprinted filenames (e.g.app.abc123.css). - For large-scale apps, serve static files from a CDN and use Nimbus only for the API and server-rendered pages.