diff --git a/docker-compose.yml b/docker-compose.yml index 67c6ae8..55fb5ce 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -30,6 +30,11 @@ services: - "5173:5173" depends_on: - app + environment: + # Vite dev-server proxy target. Inside the compose network, the + # backend service is reachable at http://app:8000. The browser + # still hits http://localhost:5173/api/v1/* and Vite proxies it. + - VITE_API_PROXY_TARGET=http://app:8000 # Bind-mount the source so Vite HMR sees host edits. node_modules stays # inside the container so platform-native deps aren't shadowed. volumes: diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 8b0f57b..8ca63ba 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -1,7 +1,26 @@ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' +// `/api/*` calls from the React app are proxied to the FastAPI backend so +// the dev experience matches a same-origin production deployment. Without +// this Vite serves `index.html` for `/api/*`, which the browser then tries +// to JSON.parse — producing "Unexpected token '<'". +// +// Override the target via env when needed: +// - Local (no Docker): defaults to http://localhost:8000. +// - docker-compose: set VITE_API_PROXY_TARGET=http://app:8000 (inside +// the compose network the backend hostname is `app`). +const API_PROXY_TARGET = process.env.VITE_API_PROXY_TARGET ?? 'http://localhost:8000' + // https://vite.dev/config/ export default defineConfig({ plugins: [react()], + server: { + proxy: { + '/api': { + target: API_PROXY_TARGET, + changeOrigin: true, + }, + }, + }, })