:3000 { root * /usr/share/caddy # Compress text responses only. woff2/png and other binaries are already # compressed, so they're excluded — re-compressing them burns CPU for ~0%. encode { zstd gzip match { header Content-Type text/* header Content-Type application/javascript* header Content-Type application/json* header Content-Type image/svg+xml* } } # Vite emits all build output under /assets/ with content-hashed filenames, # so those bytes never change for a given URL — cache them indefinitely. @assets path /assets/* header @assets Cache-Control "public, max-age=31536000, immutable" # The HTML shell is the un-hashed entry point; it must revalidate so a new # deploy is served immediately rather than from a stale cache. header /index.html Cache-Control "no-cache" try_files {path} /index.html file_server }