Why this matters
Explicit headers and MIME types avoid stale assets and incorrect rendering.
Configure UseStaticFiles with OnPrepareResponse to set "Cache-Control: public, max-age=31536000, immutable" for hashed assets and "no-cache" for HTML; ensure correct Content-Type (e.g., "font/woff2", "text/css").
Explicit headers and MIME types avoid stale assets and incorrect rendering.
Side-by-side examples engineers can pattern-match during review.
app.UseStaticFiles(); // default caching and typesapp.UseStaticFiles(new StaticFileOptions{ OnPrepareResponse = ctx => { var p = ctx.File.Name; if(hashRegex.IsMatch(p)) ctx.Context.Response.Headers["Cache-Control"] = "public, max-age=31536000, immutable"; else if(p.EndsWith(".html")) ctx.Context.Response.Headers["Cache-Control"] = "no-cache"; } });ctx.Context.Response.Headers["Cache-Control"] = "public, max-age=31536000, immutable"app.UseStaticFiles(); // 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).