| name | vite-proxy-folder-name-conflict |
| description | Fix 404 errors for frontend JS files when using Vite proxy. Use when: (1) Browser shows
"Failed to load resource: 404" for JS/JSX files that exist on disk, (2) Vite serves HTML
instead of JavaScript for module imports, (3) You have a client folder named "api" (or
similar) AND a Vite proxy configured for "/api". The proxy intercepts requests for
client-side files when folder names match proxy paths. Applies to Vite, Vite+React,
Vite+Vue projects with dev server proxy configuration.
|
| author | Claude Code |
| version | 1.0.0 |
| date | "2026-01-21T00:00:00.000Z" |
Vite Proxy Folder Name Conflict
Problem
Frontend JavaScript/JSX files return 404 errors even though they exist on disk. The browser
console shows errors like:
usePeople.js:1 Failed to load resource: the server responded with a status of 404 (Not Found)
useMedia.js:1 Failed to load resource: the server responded with a status of 404 (Not Found)
The files exist at paths like src/client/api/hooks/usePeople.js, but Vite returns 404 or
serves HTML instead of JavaScript.
Context / Trigger Conditions
This issue occurs when ALL of these conditions are true:
-
Vite dev server with proxy configuration in vite.config.js:
server: {
proxy: {
'/api': {
target: 'http://localhost:3001',
changeOrigin: true,
},
},
}
-
Client-side folder with the same name as the proxy path:
src/client/
├── api/ ← Folder name matches proxy path "/api"
│ ├── client.js
│ └── hooks/
│ ├── usePeople.js
│ └── useMedia.js
-
Imports that resolve to the proxied path:
import { usePeople } from '../api/hooks/usePeople.js';
Root Cause
Vite's module resolution transforms relative imports to absolute paths. When you import
../api/hooks/usePeople.js from a page, Vite resolves it to /api/hooks/usePeople.js.
The proxy configuration matches paths starting with /api and forwards them to the backend
server. Since /api/hooks/usePeople.js starts with /api, it gets proxied to the backend
instead of being served as a static file.
The backend doesn't have a route for /api/hooks/usePeople.js, so it returns 404.
Solution
Option 1: Rename the client folder (Recommended)
Rename the conflicting folder to something that won't match the proxy path:
mv src/client/api src/client/services
find src/client -name "*.jsx" -o -name "*.js" | xargs sed -i '' 's|from.*['"'"'"]\.\.\/api|from "../services|g'
Option 2: Use a different proxy path
Change the proxy path to something more specific:
server: {
proxy: {
'/api/v1': {
target: 'http://localhost:3001',
changeOrigin: true,
},
},
}
Option 3: Configure proxy to exclude certain patterns
Use a custom function to exclude certain paths:
server: {
proxy: {
'/api': {
target: 'http://localhost:3001',
changeOrigin: true,
bypass: (req) => {
if (req.url.match(/\.(js|jsx|ts|tsx|mjs)$/)) {
return req.url;
}
},
},
},
}
Verification
After applying the fix:
- Clear Vite's cache:
rm -rf node_modules/.vite
- Restart the dev server:
npm run dev
- Check browser console - 404 errors should be gone
- Verify the app loads and API calls still work
Test both:
- Frontend file serving:
curl http://localhost:5173/services/hooks/usePeople.js should return JavaScript
- API proxying:
curl http://localhost:5173/api/people should return JSON from backend
Example
Before (broken):
src/client/
├── api/ ← Conflicts with proxy
│ └── hooks/
│ └── usePeople.js
├── pages/
│ └── Directory.jsx ← import from '../api/hooks/usePeople.js'
vite.config.js:
proxy: { '/api': 'http://localhost:3001' }
Result: Browser gets 404 for usePeople.js
After (fixed):
src/client/
├── services/ ← Renamed to avoid conflict
│ └── hooks/
│ └── usePeople.js
├── pages/
│ └── Directory.jsx ← import from '../services/hooks/usePeople.js'
vite.config.js:
proxy: { '/api': 'http://localhost:3001' } ← Unchanged
Result: Frontend files served correctly, API still proxied
Notes
- This issue is not specific to React—it affects any Vite project with proxies
- Common conflicting folder names:
api, graphql, socket, ws
- The issue only manifests in development (Vite dev server); production builds don't have this problem
- If using TypeScript path aliases, ensure they also avoid proxy path conflicts
- Always clear Vite's cache (
node_modules/.vite) after changing folder structure
Related Issues
- Similar issues can occur with other dev servers (webpack-dev-server, Create React App)
- If using a monorepo, check proxy configs in both root and package-level configs