From 2bce4e999a7f1620458495ff355127801ff4538e Mon Sep 17 00:00:00 2001 From: Marc Brooks Date: Fri, 12 Sep 2025 01:41:41 -0500 Subject: [PATCH] chore: enhance the gzip and cacheable handling of static files Add SVG and ICO to cacheable files. Emit robots.txt directly. Recognize WOFF2 (font) files as assets (so the get the immutable treatment) Pre-gzip the entire /static/ directory (not just /static/assets/) and include SVG, ICO, and HTML files Ensure fonts.css is processed by vite/rollup so that the preload and css reference the same immutable files (which get long-cached with hashes) Add CircularXXWeb-Black to the preload list as it is used in the hot-path. Handle system-driven color-scheme changes from dark to light correctly. --- Makefile | 5 ++++- ui/index.html | 41 +++++++++++++++++++++++------------------ ui/public/robots.txt | 2 -- ui/vite.config.ts | 1 + web.go | 16 +++++++++++++--- 5 files changed, 41 insertions(+), 24 deletions(-) delete mode 100644 ui/public/robots.txt diff --git a/Makefile b/Makefile index 178e6daf..ab393b00 100644 --- a/Makefile +++ b/Makefile @@ -63,14 +63,17 @@ build_dev_test: build_test2json build_gotestsum frontend: cd ui && npm ci && npm run build:device && \ - find ../static/assets \ + find ../static/ \ -type f \ \( -name '*.js' \ -o -name '*.css' \ + -o -name '*.html' \ + -o -name '*.ico' \ -o -name '*.png' \ -o -name '*.jpg' \ -o -name '*.jpeg' \ -o -name '*.gif' \ + -o -name '*.svg' \ -o -name '*.webp' \ -o -name '*.woff2' \ \) \ diff --git a/ui/index.html b/ui/index.html index 0ce91234..a798221c 100644 --- a/ui/index.html +++ b/ui/index.html @@ -6,27 +6,34 @@ + JetKVM - + @@ -36,23 +43,21 @@ { esbuild: { pure: ["console.debug"], }, + assetsInclude: ["**/*.woff2"], build: { outDir: isCloud ? "dist" : "../static", rollupOptions: { diff --git a/web.go b/web.go index 883ebb75..f1aa1ab4 100644 --- a/web.go +++ b/web.go @@ -69,8 +69,7 @@ type SetupRequest struct { } var cachableFileExtensions = []string{ - ".jpg", ".jpeg", ".png", ".gif", ".webp", ".woff2", - ".ico", + ".jpg", ".jpeg", ".png", ".svg", ".gif", ".webp", ".ico", ".woff2", } func setupRouter() *gin.Engine { @@ -83,7 +82,10 @@ func setupRouter() *gin.Engine { }), )) - staticFS, _ := fs.Sub(staticFiles, "static") + staticFS, err := fs.Sub(staticFiles, "static") + if err != nil { + logger.Fatal().Err(err).Msg("failed to get rooted static files subdirectory") + } staticFileServer := http.StripPrefix("/static", statigz.FileServer( staticFS.(fs.ReadDirFS), )) @@ -109,9 +111,17 @@ func setupRouter() *gin.Engine { c.Next() }) + r.GET("/robots.txt", func(c *gin.Context) { + c.Header("Content-Type", "text/plain") + c.Header("Cache-Control", "public, max-age=31536000, immutable") // Cache for 1 year + c.String(http.StatusOK, "User-agent: *\nDisallow: /") + }) + r.Any("/static/*w", func(c *gin.Context) { staticFileServer.ServeHTTP(c.Writer, c.Request) }) + + // Public routes (no authentication required) r.POST("/auth/login-local", handleLogin) // We use this to determine if the device is setup