diff --git a/server/router/frontend/frontend.go b/server/router/frontend/frontend.go index 81285b38..9e589736 100644 --- a/server/router/frontend/frontend.go +++ b/server/router/frontend/frontend.go @@ -14,7 +14,7 @@ import ( "github.com/usememos/memos/store" ) -//go:embed dist +//go:embed dist/* var embeddedFiles embed.FS type FrontendService struct { @@ -34,16 +34,8 @@ func (*FrontendService) Serve(_ context.Context, e *echo.Echo) { return util.HasPrefixes(c.Path(), "/api", "/memos.api.v1") } - // Use echo static middleware to serve the built dist folder. - // Reference: https://github.com/labstack/echo/blob/master/middleware/static.go - e.Use(middleware.StaticWithConfig(middleware.StaticConfig{ - HTML5: true, - Filesystem: getFileSystem("dist"), - Skipper: skipper, - })) - // Use echo gzip middleware to compress the response. - // Reference: https://echo.labstack.com/docs/middleware/gzip - e.Group("assets").Use(middleware.GzipWithConfig(middleware.GzipConfig{ + // Route to serve the assets folder without HTML5 fallback. + e.Group("/assets").Use(middleware.GzipWithConfig(middleware.GzipConfig{ Level: 5, }), func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { @@ -52,6 +44,14 @@ func (*FrontendService) Serve(_ context.Context, e *echo.Echo) { } }, middleware.StaticWithConfig(middleware.StaticConfig{ Filesystem: getFileSystem("dist/assets"), + HTML5: false, // Disable fallback to index.html + })) + + // 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, })) } diff --git a/web/src/components/MemoContent/MermaidBlock.tsx b/web/src/components/MemoContent/MermaidBlock.tsx index b2e294af..bf558fa8 100644 --- a/web/src/components/MemoContent/MermaidBlock.tsx +++ b/web/src/components/MemoContent/MermaidBlock.tsx @@ -1,4 +1,3 @@ -import mermaid from "mermaid"; import { useEffect, useRef } from "react"; interface Props { @@ -7,18 +6,21 @@ interface Props { const MermaidBlock: React.FC = ({ content }: Props) => { const mermaidDockBlock = useRef(null); - mermaid.initialize({ startOnLoad: false, theme: "default" }); useEffect(() => { - if (!mermaidDockBlock.current) { - return; - } + // Dynamically import mermaid to ensure compatibility with Vite + const initializeMermaid = async () => { + const mermaid = (await import("mermaid")).default; + mermaid.initialize({ startOnLoad: false, theme: "default" }); + if (mermaidDockBlock.current) { + mermaid.run({ + nodes: [mermaidDockBlock.current], + }); + } + }; - // Render mermaid when mounted. - mermaid.run({ - nodes: [mermaidDockBlock.current], - }); - }); + initializeMermaid(); + }, [content]); return (
diff --git a/web/vite.config.ts b/web/vite.config.ts
index e468a1c5..260f6ef8 100644
--- a/web/vite.config.ts
+++ b/web/vite.config.ts
@@ -34,4 +34,13 @@ export default defineConfig({
       "@/": `${resolve(__dirname, "src")}/`,
     },
   },
+  build: {
+    rollupOptions: {
+      output: {
+        entryFileNames: "app.[hash].js",
+        chunkFileNames: "assets/chunk-vendors.[hash].js",
+        assetFileNames: "assets/[name].[hash][extname]",
+      },
+    },
+  },
 });