feat: add caching headers for Next.js static assets (#330)

This commit is contained in:
Jonathan Yu
2022-02-18 19:34:56 -08:00
committed by GitHub
parent 5ef59e7b64
commit f7b484929f
2 changed files with 62 additions and 4 deletions
+26 -4
View File
@@ -49,10 +49,7 @@ func Handler(fileSystem fs.FS, options *Options) (http.Handler, error) {
}
// Fallback to static file server for non-HTML files
// Non-HTML files don't have special routing rules, so we can just leverage
// the built-in http.FileServer for it.
fileHandler := http.FileServer(http.FS(fileSystem))
router.NotFound(fileHandler.ServeHTTP)
router.NotFound(FileHandler(fileSystem))
// Finally, if there is a 404.html available, serve that
err = register404(fileSystem, router, *options)
@@ -64,6 +61,31 @@ func Handler(fileSystem fs.FS, options *Options) (http.Handler, error) {
return router, nil
}
// FileHandler serves static content, additionally adding immutable
// cache-control headers for Next.js content
func FileHandler(fileSystem fs.FS) func(writer http.ResponseWriter, request *http.Request) {
// Non-HTML files don't have special routing rules, so we can just leverage
// the built-in http.FileServer for it.
fileHandler := http.FileServer(http.FS(fileSystem))
return func(writer http.ResponseWriter, request *http.Request) {
// From the Next.js documentation:
//
// "Caching improves response times and reduces the number
// of requests to external services. Next.js automatically
// adds caching headers to immutable assets served from
// /_next/static including JavaScript, CSS, static images,
// and other media."
//
// See: https://nextjs.org/docs/going-to-production
if strings.HasPrefix(request.URL.Path, "/_next/static/") {
writer.Header().Add("Cache-Control", "public, max-age=31536000, immutable")
}
fileHandler.ServeHTTP(writer, request)
}
}
// registerRoutes recursively traverses the file-system, building routes
// as appropriate for respecting NextJS dynamic rules.
func registerRoutes(rtr chi.Router, fileSystem fs.FS, options Options) error {
+36
View File
@@ -376,6 +376,42 @@ func TestNextRouter(t *testing.T) {
require.EqualValues(t, "test-create", body)
})
t.Run("Caching headers for _next resources", func(t *testing.T) {
t.Parallel()
rootFS := fstest.MapFS{
"index.html": &fstest.MapFile{
Data: []byte("test-root"),
},
"_next/static/test.js": &fstest.MapFile{
Data: []byte("test.js cached forever"),
},
"_next/static/chunks/app/test.css": &fstest.MapFile{
Data: []byte("test.css cached forever"),
},
}
router, err := nextrouter.Handler(rootFS, nil)
require.NoError(t, err)
server := httptest.NewServer(router)
t.Cleanup(server.Close)
res, err := request(server, "/index.html")
require.NoError(t, err)
require.NoError(t, res.Body.Close())
require.Equal(t, http.StatusOK, res.StatusCode)
require.Empty(t, res.Header.Get("Cache-Control"))
res, err = request(server, "/_next/static/test.js")
require.NoError(t, err)
require.NoError(t, res.Body.Close())
require.Equal(t, http.StatusOK, res.StatusCode)
require.Equal(t, "public, max-age=31536000, immutable", res.Header.Get("Cache-Control"))
})
t.Run("Injects template parameters", func(t *testing.T) {
t.Parallel()