fix: use relative Vite base; serve SPA at both /v2/ and /clawstor/

Vite base: '/clawstor/' caused 404s when the SPA was served at /v2/
because asset paths like /clawstor/assets/... didn't match the actual
serve path /v2/assets/...

- vite.config.ts: switch to base: './' (relative paths work from any
  mount point — /v2/, /clawstor/, or bare /)
- serve.rs: mount the SPA at both /v2/ and /clawstor/; add 308 redirect
  from /v2 and /clawstor (no trailing slash) to their canonical forms
  so browsers don't misinterpret the last segment as a filename and
  break relative ./assets/ resolution

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
Omar Sobh
2026-07-23 19:45:55 +00:00
co-authored by Claude Sonnet 4.6
parent a8f0aa911c
commit 5001ac233c
3 changed files with 24 additions and 14 deletions
+6 -7
View File
@@ -6,13 +6,12 @@ import react from '@vitejs/plugin-react';
// During local dev the daemon proxies /api/v2/* on :7700 so
// `vite dev` on :5173 can hit it via server.proxy.
export default defineConfig({
// Absolute base tied to the deploy path. Prior try was `./`
// (fully relative) which broke when the user hit `/clawstor`
// without trailing slash — browser resolves `./assets/…`
// against `/clawstor` treated as a file, gives `/assets/…`,
// 404 from Tailscale. Absolute `/clawstor/` sidesteps the
// slash / no-slash ambiguity.
base: '/clawstor/',
// Relative base so the SPA works under any mount point (/v2/,
// /clawstor/, or bare /). The no-trailing-slash edge case
// (browser treats the path as a file and strips the last segment)
// is handled server-side: serve.rs redirects /v2 → /v2/ and
// /clawstor → /clawstor/ before serving the SPA.
base: './',
plugins: [react()],
server: {
port: 5173,