No articles found
Try different keywords or browse our categories
How to Fix CORS Error in React Vite Project: Complete Guide 2026
Learn how to fix CORS errors in React Vite projects with step-by-step solutions. This guide covers proxy setup, server configurations, and best practices for handling cross-origin requests.
Cross-Origin Resource Sharing (CORS) errors are one of the most common challenges developers face when building React + Vite applications that communicate with external APIs. These errors occur when your React application tries to make requests to a different domain, port, or protocol than the one serving your application.
This comprehensive guide explains what CORS errors are, why they happen, and provides multiple solutions to fix them in your React Vite project with clean code examples and directory structure.
What is CORS Error?
CORS (Cross-Origin Resource Sharing) is a security feature implemented by web browsers to prevent malicious websites from making unauthorized requests to other domains. When your React application running on localhost:5173 tries to access an API on localhost:3000 or any external domain, the browser blocks the request unless the server explicitly allows it.
Common CORS Error Messages:
Access to fetch at 'http://localhost:3000/api/data' from origin 'http://localhost:5173' has been blocked by CORS policyNo 'Access-Control-Allow-Origin' header is present on the requested resource
Understanding the Problem
In a typical React + Vite setup, your development server runs on http://localhost:5173, while your backend API might run on http://localhost:3000. When your React app makes API calls to the backend, the browser enforces CORS policy and blocks these requests.
Typical Project Structure:
my-react-app/
├── index.html
├── package.json
├── vite.config.js
└── src/
├── App.jsx
├── main.jsx
├── components/
│ └── ApiComponent.jsx
└── index.css
Solution 1: Using Vite Proxy (Recommended for Development)
The most common and effective solution during development is to configure a proxy in your Vite configuration. This allows Vite to intercept API requests and forward them to your backend server.
Step 1: Update vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
server: {
proxy: {
// Proxy API requests to your backend server
'/api': {
target: 'http://localhost:3000', // Your backend server URL
changeOrigin: true,
secure: false, // Set to true if using HTTPS
// Optional: rewrite the path
rewrite: (path) => path.replace(/^\/api/, '')
},
// You can add multiple proxy rules
'/auth': {
target: 'http://localhost:3000',
changeOrigin: true,
secure: false,
}
}
}
})
Step 2: Update Your API Calls
Instead of calling the full backend URL, use the proxy path:
// src/components/ApiComponent.jsx
import { useState, useEffect } from 'react';
export default function ApiComponent() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
// Instead of http://localhost:3000/api/data, use /api/data
fetch('/api/data')
.then(response => response.json())
.then(data => {
setData(data);
setLoading(false);
})
.catch(error => {
console.error('Error fetching data:', error);
setLoading(false);
});
}, []);
if (loading) return <div>Loading...</div>;
return (
<div className="p-4">
<h2 className="text-xl font-bold mb-2">API Data</h2>
<pre className="bg-gray-100 p-2 rounded">{JSON.stringify(data, null, 2)}</pre>
</div>
);
}
Solution 2: Backend Server Configuration (Production Ready)
For production environments, you need to configure CORS on your backend server. Here are examples for different backend technologies:
Express.js Backend Configuration
// server.js (your backend server)
const express = require('express');
const cors = require('cors');
const app = express();
// CORS configuration
const corsOptions = {
origin: [
'http://localhost:5173', // React Vite dev server
'http://localhost:3000', // If needed
'https://yourdomain.com', // Production domain
'https://www.yourdomain.com'
],
credentials: true,
optionsSuccessStatus: 200
};
app.use(cors(corsOptions));
// Your API routes
app.get('/api/data', (req, res) => {
res.json({ message: 'Hello from backend!' });
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
Alternative: Simple CORS Setup
// Simple CORS setup for development
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
if (req.method === 'OPTIONS') {
res.sendStatus(200);
} else {
next();
}
});
Solution 3: Environment-Based Configuration
Create environment-specific configurations to handle different environments:
Step 1: Create Environment Files
# .env.development
VITE_API_URL=http://localhost:3000
# .env.production
VITE_API_URL=https://api.yourdomain.com
Step 2: Update vite.config.js for Environment Handling
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig(({ mode }) => {
const config = {
plugins: [react()],
};
if (mode === 'development') {
config.server = {
proxy: {
'/api': {
target: process.env.VITE_API_URL || 'http://localhost:3000',
changeOrigin: true,
secure: false,
}
}
};
}
return config;
});
Step 3: Use Environment Variables in Components
// src/components/ApiComponent.jsx
import { useState, useEffect } from 'react';
export default function ApiComponent() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
// Use environment variable for API calls
const apiUrl = import.meta.env.VITE_API_URL || '/api';
fetch(`${apiUrl}/data`)
.then(response => response.json())
.then(data => {
setData(data);
setLoading(false);
})
.catch(error => {
console.error('Error fetching data:', error);
setLoading(false);
});
}, []);
if (loading) return <div>Loading...</div>;
return (
<div className="p-4">
<h2 className="text-xl font-bold mb-2">API Data</h2>
<pre className="bg-gray-100 p-2 rounded">{JSON.stringify(data, null, 2)}</pre>
</div>
);
}
Solution 4: Using a Browser Extension (Temporary Fix)
For quick testing, you can use browser extensions like “CORS Unblock” or “Allow CORS”. However, this is not recommended for production as it only works in development and can be a security risk.
Complete Project Structure After CORS Fix
my-react-app/
├── .env.development
├── .env.production
├── index.html
├── package.json
├── vite.config.js
└── src/
├── App.jsx
├── main.jsx
├── components/
│ └── ApiComponent.jsx
└── index.css
Best Practices for Handling CORS
1. Never Use Wildcard in Production
// ❌ Don't do this in production
app.use(cors({
origin: '*' // This allows all origins
}));
// ✅ Do this instead
app.use(cors({
origin: ['https://yourdomain.com', 'https://www.yourdomain.com']
}));
2. Use Specific Endpoints for Proxy
// vite.config.js
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
},
'/auth': {
target: 'http://localhost:3000',
changeOrigin: true,
}
}
3. Handle Credentials Properly
// If you need to send cookies or authentication headers
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
secure: false,
credentials: 'include', // If needed
}
}
Testing Your CORS Configuration
1. Check Network Tab
Open browser developer tools and check the Network tab for your API requests. Look for:
- Status codes (should be 200, not 0)
- Response headers
- No CORS-related error messages
2. Console Errors
Check the browser console for any CORS-related error messages.
3. Test Different Endpoints
Test various API endpoints to ensure CORS is properly configured for all routes.
Common CORS Issues and Solutions
Issue 1: Preflight Requests
// If you're making complex requests (PUT, DELETE, custom headers)
// Make sure your server handles OPTIONS requests
app.options('*', cors(corsOptions));
Issue 2: Multiple Origins
// Handle multiple origins dynamically
const allowedOrigins = [
'http://localhost:5173',
'https://yourdomain.com',
'https://www.yourdomain.com'
];
const corsOptions = {
origin: (origin, callback) => {
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
}
};
Performance Considerations
1. Cache CORS Responses
// Cache preflight responses
app.use((req, res, next) => {
res.header('Access-Control-Max-Age', '86400'); // 24 hours
next();
});
2. Minimize CORS Headers
Only include necessary CORS headers to reduce response size.
Security Considerations
1. Validate Origins
Always validate and restrict allowed origins to prevent security vulnerabilities.
2. Limit Credentials
Only use credentials when absolutely necessary.
3. Use HTTPS in Production
Always use HTTPS for production applications to ensure secure communication.
Conclusion
Fixing CORS errors in React Vite projects requires understanding both the frontend and backend configurations. The Vite proxy solution is the most effective for development, while backend CORS configuration is essential for production.
By following this guide, you can successfully resolve CORS issues in your React Vite applications and ensure smooth communication between your frontend and backend services. Remember to implement proper security measures and test thoroughly in different environments.
With these solutions implemented, your React Vite application will be able to communicate with external APIs without CORS-related issues, providing a seamless user experience.
Related Articles
Fix: process is not defined error in React Vite - Complete Solution Guide
Learn how to fix the 'process is not defined' error in React Vite projects. This guide covers environment variables, Node.js compatibility, and best practices for Vite configuration.
Fix: Invalid React hook call. Hooks can only be called inside of the body of a function component
Learn how to fix the 'Invalid hook call' error in React. This guide covers all causes, solutions, and best practices for proper React hook usage with step-by-step examples.
Fix: Module not found: Can't resolve 'react/jsx-runtime' - Complete Solution Guide
Learn how to fix the 'Module not found: Can't resolve react/jsx-runtime' error in React projects. This guide covers causes, solutions, and prevention strategies with step-by-step instructions.