Why this matters
Built-in Ktor features simplify correct caching and compression for static assets.
In Kotlin Ktor, install CachingHeaders and Compression. Set immutable caching for hashed resources and no-cache for HTML; include "Vary: Accept-Encoding".
Built-in Ktor features simplify correct caching and compression for static assets.
Side-by-side examples engineers can pattern-match during review.
static("/assets"){ files("/public") } // no caching/compressioninstall(Compression)\ninstall(CachingHeaders){ options { outgoingContent -> if(outgoingContent.contentType?.withoutParameters() == ContentType.Text.Html) CachingOptions(CacheControl.NoCache(null)) else CachingOptions(CacheControl.MaxAge(365246060, visibility = CacheControl.Visibility.Public)) } }\nstatic(\"/assets\"){ files(\"public\") }install(CachingHeaders)static("/assets"){ files("public") } // defaultsFrom the same buckets as this rule.
All static JS/CSS/font/image files MUST use content-hashed filenames (e.g., app.9c1a7b.js) and be served with "Cache-Control: public, max-age=31536000, immutable". HTML and other non-fingerprinted documents MUST be served with "Cache-Control: no-cache" (or equivalent) to enable conditional revalidation.
Serve text-based assets (JS, CSS, JSON, SVG) with Brotli (br) when the client sends "Accept-Encoding: br" and fallback to gzip. Always set "Vary: Accept-Encoding" and do NOT compress already-compressed formats (e.g., .png, .jpg, .woff2).