mirror of
https://github.com/usememos/memos.git
synced 2025-12-17 22:28:52 +08:00
Changed Cache-Control max-age from 7 days to 1 hour with immutable directive. This prevents users from experiencing blank pages or JS errors when accessing frequently redeployed instances (e.g., demo environments) where old cached assets may reference files that no longer exist after redeployment. Since Vite generates content-hashed filenames, the immutable directive prevents unnecessary revalidation while the shorter cache duration ensures fresh assets are served within an hour of redeployment. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
65 lines
1.7 KiB
Go
65 lines
1.7 KiB
Go
package frontend
|
|
|
|
import (
|
|
"context"
|
|
"embed"
|
|
"io/fs"
|
|
"net/http"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/labstack/echo/v4/middleware"
|
|
|
|
"github.com/usememos/memos/internal/profile"
|
|
"github.com/usememos/memos/internal/util"
|
|
"github.com/usememos/memos/store"
|
|
)
|
|
|
|
//go:embed dist/*
|
|
var embeddedFiles embed.FS
|
|
|
|
type FrontendService struct {
|
|
Profile *profile.Profile
|
|
Store *store.Store
|
|
}
|
|
|
|
func NewFrontendService(profile *profile.Profile, store *store.Store) *FrontendService {
|
|
return &FrontendService{
|
|
Profile: profile,
|
|
Store: store,
|
|
}
|
|
}
|
|
|
|
func (*FrontendService) Serve(_ context.Context, e *echo.Echo) {
|
|
skipper := func(c echo.Context) bool {
|
|
// Skip API routes.
|
|
if util.HasPrefixes(c.Path(), "/api", "/memos.api.v1") {
|
|
return true
|
|
}
|
|
// Skip setting cache headers for index.html
|
|
if c.Path() == "/" || c.Path() == "/index.html" {
|
|
return false
|
|
}
|
|
// Set Cache-Control header for static assets.
|
|
// Since Vite generates content-hashed filenames (e.g., index-BtVjejZf.js),
|
|
// we can cache aggressively but use immutable to prevent revalidation checks.
|
|
// For frequently redeployed instances, use shorter max-age (1 hour) to avoid
|
|
// serving stale assets after redeployment.
|
|
c.Response().Header().Set(echo.HeaderCacheControl, "public, max-age=3600, immutable") // 1 hour
|
|
return false
|
|
}
|
|
|
|
// Route to serve the main app with HTML5 fallback for SPA behavior.
|
|
e.Use(middleware.StaticWithConfig(middleware.StaticConfig{
|
|
Filesystem: getFileSystem("dist"),
|
|
HTML5: true, // Enable fallback to index.html
|
|
Skipper: skipper,
|
|
}))
|
|
}
|
|
|
|
func getFileSystem(path string) http.FileSystem {
|
|
fs, err := fs.Sub(embeddedFiles, path)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return http.FS(fs)
|
|
}
|