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.
Scanned 9/3/2026
Install to Claude Code
npx -y skills add divinevideo/divine-mobile --skill vite-proxy-folder-name-conflict --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Vite Proxy Folder Name Conflict?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/divinevideo-vite-proxy-folder-name-conflict-divine-mobile)More formats (shields.io, HTML) on the badges page.
---
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-21
---
# 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:
1. **Vite dev server** with proxy configuration in `vite.config.js`:
```javascript
server: {
proxy: {
'/api': {
target: 'http://localhost:3001',
changeOrigin: true,
},
},
}
```
2. **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
```
3. **Imports** that resolve to the proxied path:
```javascript
// In src/client/pages/Directory.jsx
import { usePeople } from '../api/hooks/usePeople.js';
// Vite transforms this to: /api/hooks/usePeople.js
// This matches the proxy rule and gets sent to backend!
```
## 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:
```bash
# Rename api to services (or lib, helpers, etc.)
mv src/client/api src/client/services
# Update all imports
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:
```javascript
// vite.config.js
server: {
proxy: {
'/api/v1': { // More specific path
target: 'http://localhost:3001',
changeOrigin: true,
},
},
}
```
**Option 3: Configure proxy to exclude certain patterns**
Use a custom function to exclude certain paths:
```javascript
server: {
proxy: {
'/api': {
target: 'http://localhost:3001',
changeOrigin: true,
bypass: (req) => {
// Don't proxy requests for JS/TS files
if (req.url.match(/\.(js|jsx|ts|tsx|mjs)$/)) {
return req.url;
}
},
},
},
}
```
## Verification
After applying the fix:
1. Clear Vite's cache: `rm -rf node_modules/.vite`
2. Restart the dev server: `npm run dev`
3. Check browser console - 404 errors should be gone
4. 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
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!