From 95b5de16356bb2e6ada0935d3c68fe16634988f9 Mon Sep 17 00:00:00 2001 From: Talha Ahmed Date: Thu, 27 Aug 2026 11:46:28 +0500 Subject: [PATCH] Vite dev proxy: serve the SPA shell for browser navigations to API-prefixed routes Several API prefixes double as SPA routes (/jobs, /inbox, /pipeline, ...); refreshing the browser on one proxied the navigation to the backend and 500d. Navigations send Accept: text/html and now bypass to /index.html, while fetch/XHR traffic still proxies. VITE_API_TARGET repoints the proxy when the API is not on 8000. Verified: direct loads of /jobs, /inbox, /pipeline, /analytics, /offers render the correct screen with the session intact; /health still proxies. Co-Authored-By: Claude Fable 5 --- frontend/vite.config.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 2f34a4e..e6f9c7b 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -20,10 +20,21 @@ export default defineConfig({ port: 5173, // Same-origin style for local Vite when VITE_API_BASE is empty. // Requires API published on the host (docker-compose.host-ports.yml). + // VITE_API_TARGET repoints the proxy when the API runs elsewhere + // (e.g. 8001 locally because another service holds 8000). proxy: { '^/(health|users|roles|permissions|permission-tags|email|job|jobs|candidate|notes|interview|feedback|activity|pipeline|notifications|analytics|offers|tasks|assessments|org-settings|saved-searches|search|documents|sheet|managers|inbox)(/|$)': { - target: 'http://127.0.0.1:8000', + target: process.env.VITE_API_TARGET || 'http://127.0.0.1:8000', changeOrigin: true, + // Several API prefixes double as SPA routes (/jobs, /inbox, …). + // A browser NAVIGATION to one of them — refresh, pasted URL — + // sends Accept: text/html and wants the app shell, not the API; + // without this it proxied and 500'd. fetch/XHR traffic never + // asks for text/html (downloads go fetch→blob), so only real + // page loads are bypassed. + bypass(req) { + if (req.headers.accept?.includes('text/html')) return '/index.html' + }, }, }, },