IntegrationsVITE
Fixing your Vite proxy setup for production
Requests routed through server.proxy work during local development and fail immediately after deployment. The dev server terminates when you build static assets, leaving the browser to contact endpoints directly.
How the Vite dev proxy works
In development, your browser sends API requests directly to the Vite local dev server. Because the frontend and the requested path share the same port and host, the browser treats the call as a same-origin request. Vite forwards the request over Node.js to the upstream API, receives the response, and hands it back to your browser. Node.js does not enforce browser origin checks, so cross-origin restrictions never trigger.
import { defineConfig } from 'vite';
export default defineConfig({
server: {
proxy: {
// The browser calls /api/... and the dev server forwards it server-side
'/api': {
target: 'https://api.example.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
});Running vite build compiles HTML, JavaScript, and CSS into a static output directory. The Node.js dev server does not ship with this output. Once deployed to static hosting, the forwarding logic defined in your configuration file ceases to run.
Why requests fail after deployment
Static web hosts serve files from storage disks. When your deployed client code calls fetch('/api/users'), the browser resolves that relative path against your static host domain. The host looks for an actual file matching that path and returns a 404 status code or falls back to your index.html file.
Changing the client code to target the absolute upstream URL exposes the browser to standard cross-origin restrictions. If the upstream server omits appropriate headers, the browser drops the response. The server.cors setting described in the Vite server options controls the Vite dev server itself, meaning it has no effect on production hosting.
Production options for API requests
Resolving production fetch failures requires moving the routing or origin handling into production infrastructure. You have three paths depending on your control over the upstream service.
- Update the target API to return
Access-Control-Allow-Originmatching your production domain. This approach is standard when you maintain the backend service. - Deploy serverless routes or a reverse proxy on your hosting provider to relay calls to the upstream API. This preserves relative paths like
/apion production domains. - Route browser calls through a public proxy such as cors.dev for supported public APIs. Traffic passing through a third-party proxy can be observed by the proxy operator, making this option suitable for public data only.
# .env.development — through the dev proxy
VITE_API_BASE=/api
# .env.production — the path that works from your deployed origin
# (your own API route, or any public HTTPS API through cors.dev)
VITE_API_BASE=https://proxy.cors.dev/https://api.example.comStoring the target base URL in a Vite environment variable keeps local and production targets distinct without code modifications. Vite injects import.meta.env.VITE_API_BASE_URL at build time based on your active environment file.
Production deployment checklist
Verify your network topology and configuration values before pushing code to production hosts.
- Trace the full network path each API request takes in the compiled application bundle.
- Define production environment variables in your hosting dashboard before running the build step.
- Test requests directly from your deployed origin rather than testing against localhost.
- Inspect the browser console to identify whether a failure stems from a blocked preflight or missing response headers.
- Configure appropriate polling intervals or caching headers if your interface pulls live data.
- Ensure private API credentials and secret tokens stay off the client bundle completely.
Good questions.
Does server.cors fix my production CORS error?
No. The server.cors configuration option applies exclusively to the Vite development server. It configures which origins may connect to your local dev server while it runs on your machine. Static builds produced by vite build do not include Vite server runtime code.
Can I keep using the proxy path in production?
Yes, provided your production hosting layer implements routing rules for that path. Platforms with edge rewrites or serverless functions can map paths like /api to upstream endpoints. Without those hosting-level rewrite rules, relative paths resolve against static assets and fail.
It works on localhost:4173 (vite preview) but not on the deployed site. Why?
vite preview boots a local Node.js server for your built files, and its preview.proxy option inherits your server.proxy rules by default. The same relative paths that fail on a deployed static host keep working under preview because the local Node.js process still forwards them. Static hosting has no equivalent process, so the paths resolve to files that do not exist.