The site sits behind a CDN and shipped static assets with no Cache-Control and no versioning, so browsers/CDN kept serving stale css/js after a deploy (the "design didn't change" symptom). - HTML responses now send Cache-Control: no-cache, no-store, must-revalidate so the page itself is always revalidated. - Static assets get a long cache and are fingerprinted via asp-append-version (/css/site.css?v=<contenthash>), so they bust automatically on every change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -9,8 +9,8 @@
|
||||
@@font-face { font-family:'SpaceMono'; src:url('/fonts/SpaceMono-Regular.woff2') format('woff2'); font-display:swap; }
|
||||
</style>
|
||||
<!-- Tailwind: prebuilt + purged admin stylesheet (`npm run build`). No runtime CDN. -->
|
||||
<link rel="stylesheet" href="/css/tailwind-admin.css" />
|
||||
<link rel="stylesheet" href="/css/site.css" />
|
||||
<link rel="stylesheet" href="/css/tailwind-admin.css" asp-append-version="true" />
|
||||
<link rel="stylesheet" href="/css/site.css" asp-append-version="true" />
|
||||
</head>
|
||||
<body class="min-h-screen bg-base text-slate-200 antialiased">
|
||||
<div class="flex min-h-screen">
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
</style>
|
||||
|
||||
<!-- Tailwind: prebuilt + purged stylesheet (`npm run build`). No runtime CDN. -->
|
||||
<link rel="stylesheet" href="/css/tailwind.css" />
|
||||
<link rel="stylesheet" href="/css/site.css" />
|
||||
<link rel="icon" href="/logo-mark.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="/css/tailwind.css" asp-append-version="true" />
|
||||
<link rel="stylesheet" href="/css/site.css" asp-append-version="true" />
|
||||
<link rel="icon" href="/logo-mark.svg" type="image/svg+xml" asp-append-version="true" />
|
||||
</head>
|
||||
<body class="site antialiased">
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/js/app.js" defer></script>
|
||||
<script src="/js/app.js" defer asp-append-version="true"></script>
|
||||
@await RenderSectionAsync("Scripts", required: false)
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+23
-1
@@ -50,7 +50,29 @@ using (var scope = app.Services.CreateScope())
|
||||
}
|
||||
|
||||
app.UseStatusCodePagesWithReExecute("/Error/{0}");
|
||||
app.UseStaticFiles();
|
||||
|
||||
// HTML pages must never be cached by the browser or CDN, so a new deploy is
|
||||
// visible immediately. Static assets are fingerprinted via asp-append-version
|
||||
// (?v=hash), so they can be cached aggressively and bust automatically.
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
context.Response.OnStarting(() =>
|
||||
{
|
||||
if (context.Response.ContentType?.Contains("text/html", StringComparison.OrdinalIgnoreCase) == true)
|
||||
{
|
||||
context.Response.Headers.CacheControl = "no-cache, no-store, must-revalidate";
|
||||
context.Response.Headers.Pragma = "no-cache";
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
await next();
|
||||
});
|
||||
|
||||
app.UseStaticFiles(new StaticFileOptions
|
||||
{
|
||||
OnPrepareResponse = ctx =>
|
||||
ctx.Context.Response.Headers.CacheControl = "public, max-age=31536000"
|
||||
});
|
||||
|
||||
// Serve uploaded files from /data/uploads under /uploads/*
|
||||
var uploadsPath = Path.Combine(dataDir, "uploads");
|
||||
|
||||
Reference in New Issue
Block a user