From 9c93d945342e0c4c0e7b1a264dfdb77b9afe0b31 Mon Sep 17 00:00:00 2001 From: Nika Siradze Date: Wed, 10 Jun 2026 16:58:01 +0400 Subject: [PATCH] fix: serve built SPA from dist when web-server runs from source npm run ui (tsx src/ui) resolved the static dir to src/ui/public, which has no index.html (vite build emits it to dist/ui/public), causing ENOENT on page load. Fall back to the built output when running from source. --- src/ui/web-server.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ui/web-server.ts b/src/ui/web-server.ts index b2a0bde..36b1212 100644 --- a/src/ui/web-server.ts +++ b/src/ui/web-server.ts @@ -50,6 +50,11 @@ import type { const log = childLogger("web-server"); const __dirname = dirname(fileURLToPath(import.meta.url)); + +const publicDir = existsSync(join(__dirname, "public", "index.html")) + ? join(__dirname, "public") + : resolve(__dirname, "..", "..", "dist", "ui", "public"); + const app = express(); const PORT = parseInt(process.env.PORT || "3847"); @@ -299,7 +304,7 @@ function createBatchHistoryRecorder({ app.use(express.json({ limit: "50mb" })); // Serve static frontend -app.use(express.static(join(__dirname, "public"))); +app.use(express.static(publicDir)); // File upload config const uploadDir = join(paths.working, "uploads"); @@ -2366,7 +2371,7 @@ async function main() { // SPA fallback: client-side routes (/, /episode, /clip/:id) resolve to the // built index.html. Registered last so it never shadows /api or static assets. app.get(/^(?!\/api\/).*/, (_req, res) => { - res.sendFile(join(__dirname, "public", "index.html")); + res.sendFile(join(publicDir, "index.html")); }); app.listen(PORT, () => {