From ca8b06f4cf3a52a962b2f3616bfe8afe0bb53a1a 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 178e6da..ab393b0 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 0ce9123..a798221 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 883ebb7..f1aa1ab 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