Vite inlines import.meta.env.PUBLIC_* at build time, not runtime. Without this, the frontend falls back to localhost:8099 which doesn't exist from the browser. Empty string means same-origin requests, letting Caddy route /api/* to the backend.
Vite inlines import.meta.env.PUBLIC_* at build time, not runtime. Without this, the frontend falls back to localhost:8099 which doesn't exist from the browser. Empty string means same-origin requests, letting Caddy route /api/* to the backend.