Fix stale block page preview by cache-busting static assets
The preview iframe stayed blank after a redeploy because /static/js/app.js is served with a 24h Cache-Control and no versioning, so browsers kept using the pre-existing cached copy that predated the preview code. Static CSS/JS references now carry a ?v=<build commit> query string so a new build is never masked by a stale cache. Also makes the CSP's frame-src explicit for the preview iframe rather than relying on the default-src fallback. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TTKpGMQzpfDsvedu1hvSUf
This commit is contained in:
@@ -30,12 +30,24 @@ type PageData struct {
|
|||||||
Flashes []Flash
|
Flashes []Flash
|
||||||
Alerts []Alert
|
Alerts []Alert
|
||||||
Version string
|
Version string
|
||||||
|
Asset string // cache-busting suffix for /static URLs; changes every build
|
||||||
Now time.Time
|
Now time.Time
|
||||||
Data any
|
Data any
|
||||||
Query url.Values
|
Query url.Values
|
||||||
BasePath string
|
BasePath string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// assetVersion busts the browser cache for /static assets on every new
|
||||||
|
// build, so a redeploy is never masked by a day-old cached app.js. It falls
|
||||||
|
// back to the semantic version when no VCS commit was embedded (e.g. a build
|
||||||
|
// outside a git checkout), which is still stable within one running process.
|
||||||
|
var assetVersion = func() string {
|
||||||
|
if version.Commit != "" {
|
||||||
|
return version.Commit
|
||||||
|
}
|
||||||
|
return version.Version
|
||||||
|
}()
|
||||||
|
|
||||||
// Alert is a persistent banner such as "a restart is required".
|
// Alert is a persistent banner such as "a restart is required".
|
||||||
type Alert struct {
|
type Alert struct {
|
||||||
Level string // warning, danger, info
|
Level string // warning, danger, info
|
||||||
@@ -94,6 +106,7 @@ func (s *Server) render(w http.ResponseWriter, r *http.Request, page string, dat
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.Version = version.Version
|
data.Version = version.Version
|
||||||
|
data.Asset = assetVersion
|
||||||
data.Now = time.Now()
|
data.Now = time.Now()
|
||||||
if data.Query == nil {
|
if data.Query == nil {
|
||||||
data.Query = r.URL.Query()
|
data.Query = r.URL.Query()
|
||||||
@@ -126,6 +139,7 @@ func (s *Server) renderError(w http.ResponseWriter, r *http.Request, status int,
|
|||||||
data := PageData{
|
data := PageData{
|
||||||
Title: http.StatusText(status),
|
Title: http.StatusText(status),
|
||||||
Version: version.Version,
|
Version: version.Version,
|
||||||
|
Asset: assetVersion,
|
||||||
Now: time.Now(),
|
Now: time.Now(),
|
||||||
Data: map[string]any{
|
Data: map[string]any{
|
||||||
"Status": status,
|
"Status": status,
|
||||||
|
|||||||
@@ -418,6 +418,7 @@ func (s *Server) withSecurityHeaders(next http.Handler) http.Handler {
|
|||||||
"font-src 'self'; "+
|
"font-src 'self'; "+
|
||||||
"connect-src 'self'; "+
|
"connect-src 'self'; "+
|
||||||
"form-action 'self'; "+
|
"form-action 'self'; "+
|
||||||
|
"frame-src 'self'; "+
|
||||||
"frame-ancestors 'none'; "+
|
"frame-ancestors 'none'; "+
|
||||||
"base-uri 'none'; "+
|
"base-uri 'none'; "+
|
||||||
"object-src 'none'")
|
"object-src 'none'")
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<link rel="icon" href="/static/img/favicon.svg" type="image/svg+xml">
|
<link rel="icon" href="/static/img/favicon.svg" type="image/svg+xml">
|
||||||
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
|
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
|
||||||
<link rel="stylesheet" href="/static/css/bootstrap-icons.min.css">
|
<link rel="stylesheet" href="/static/css/bootstrap-icons.min.css">
|
||||||
<link rel="stylesheet" href="/static/css/app.css">
|
<link rel="stylesheet" href="/static/css/app.css?v={{.Asset}}">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/static/js/bootstrap.bundle.min.js"></script>
|
<script src="/static/js/bootstrap.bundle.min.js"></script>
|
||||||
<script src="/static/js/app.js"></script>
|
<script src="/static/js/app.js?v={{.Asset}}"></script>
|
||||||
{{block "scripts" .}}{{end}}
|
{{block "scripts" .}}{{end}}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user