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; }
|
@@font-face { font-family:'SpaceMono'; src:url('/fonts/SpaceMono-Regular.woff2') format('woff2'); font-display:swap; }
|
||||||
</style>
|
</style>
|
||||||
<!-- Tailwind: prebuilt + purged admin stylesheet (`npm run build`). No runtime CDN. -->
|
<!-- Tailwind: prebuilt + purged admin stylesheet (`npm run build`). No runtime CDN. -->
|
||||||
<link rel="stylesheet" href="/css/tailwind-admin.css" />
|
<link rel="stylesheet" href="/css/tailwind-admin.css" asp-append-version="true" />
|
||||||
<link rel="stylesheet" href="/css/site.css" />
|
<link rel="stylesheet" href="/css/site.css" asp-append-version="true" />
|
||||||
</head>
|
</head>
|
||||||
<body class="min-h-screen bg-base text-slate-200 antialiased">
|
<body class="min-h-screen bg-base text-slate-200 antialiased">
|
||||||
<div class="flex min-h-screen">
|
<div class="flex min-h-screen">
|
||||||
|
|||||||
@@ -26,9 +26,9 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<!-- Tailwind: prebuilt + purged stylesheet (`npm run build`). No runtime CDN. -->
|
<!-- Tailwind: prebuilt + purged stylesheet (`npm run build`). No runtime CDN. -->
|
||||||
<link rel="stylesheet" href="/css/tailwind.css" />
|
<link rel="stylesheet" href="/css/tailwind.css" asp-append-version="true" />
|
||||||
<link rel="stylesheet" href="/css/site.css" />
|
<link rel="stylesheet" href="/css/site.css" asp-append-version="true" />
|
||||||
<link rel="icon" href="/logo-mark.svg" type="image/svg+xml" />
|
<link rel="icon" href="/logo-mark.svg" type="image/svg+xml" asp-append-version="true" />
|
||||||
</head>
|
</head>
|
||||||
<body class="site antialiased">
|
<body class="site antialiased">
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<script src="/js/app.js" defer></script>
|
<script src="/js/app.js" defer asp-append-version="true"></script>
|
||||||
@await RenderSectionAsync("Scripts", required: false)
|
@await RenderSectionAsync("Scripts", required: false)
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+23
-1
@@ -50,7 +50,29 @@ using (var scope = app.Services.CreateScope())
|
|||||||
}
|
}
|
||||||
|
|
||||||
app.UseStatusCodePagesWithReExecute("/Error/{0}");
|
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/*
|
// Serve uploaded files from /data/uploads under /uploads/*
|
||||||
var uploadsPath = Path.Combine(dataDir, "uploads");
|
var uploadsPath = Path.Combine(dataDir, "uploads");
|
||||||
|
|||||||
Reference in New Issue
Block a user