Proper CORS Configuration for API Calls in React Applications
Cross-Origin Resource Sharing (CORS) issues are common when making API requests from React applications to different domains. Here’s how to properly handle CORS in your frontend and backend.
The CORS Problem
// ❌ Typical error when CORS isn't configured
fetch('https://api.example.com/data')
.then(response => response.json())
.catch(error => console.error('CORS error:', error));
// Error message:
// Access to fetch at 'https://api.example.com/data' from origin 'http://localhost:3000'
// has been blocked by CORS policy
Client-Side Solutions
1. Proper CORS Configuration (Backend)
The best solution is to configure CORS properly on your backend:
// ✅ Express.js example
const express = require('express');
const cors = require('cors');
const app = express();
// Enable CORS for all routes
app.use(cors());
// Or configure specific options
app.use(cors({
origin: 'http://localhost:3000', // Your React app's origin
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization']
}));
2. Proxy Server in Development
For Create React App, use the proxy
field in package.json
:
// package.json
{
"proxy": "http://localhost:5000" // Your backend server
}
Then make requests to relative paths:
// ✅ All requests will be proxied to backend
fetch('/api/data') // Goes to http://localhost:5000/api/data
.then(response => response.json())
3. Custom Proxy Setup (Alternative)
For more control, set up a custom proxy configuration:
// src/setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
})
);
};
Production Solutions
1. Environment-Based API URLs
// Configure different API endpoints for dev/prod
const API_URL = process.env.NODE_ENV === 'development'
? 'http://localhost:5000'
: 'https://api.yourdomain.com';
fetch(`${API_URL}/data`)
2. Server-Side Rendering (SSR)
With Next.js or other SSR frameworks, API calls can be made server-side where CORS doesn’t apply.
Temporary Development Solutions (Not for Production)
1. Browser Extension (Dev Only)
Install a CORS-unblocking extension like “Moesif CORS” for development.
2. Disable Browser Security (Chrome – Dev Only)
# Launch Chrome with disabled security (macOS/Linux)
google-chrome --disable-web-security --user-data-dir=/tmp/chrome-dev
Best Practices
- Configure CORS properly on your backend – this is the correct solution
- Use environment variables for API endpoints
- Implement proper error handling for CORS issues
- Document your API CORS requirements for other developers
- Consider authentication headers if your API requires them
// Example with authentication headers
fetch('https://api.example.com/data', {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
})
Common CORS Misconfigurations
- Missing OPTIONS method – Preflight requests require this
- Incorrect headers – Missing
Access-Control-Allow-Headers
- Wrong credentials handling – If using cookies, need
credentials: 'include'
- Overly permissive settings – Avoid
Access-Control-Allow-Origin: *
with credentials
// Proper credentials handling
fetch('https://api.example.com/data', {
credentials: 'include' // For cookies/auth
})
Remember that CORS is a browser security feature, not something to “fix” on the frontend. The permanent solution always involves proper backend configuration. For production, never use workarounds that disable security – always configure your server correctly.