How to Fix 'Blocked by CORS Policy' Error in React Apps

intermediate⚛️ React2026-04-14| React (Create React App, Vite, Next.js), Node.js/Express, Python/FastAPI, Go, PHP

Error Message

Access to fetch at 'http://api.example.com' from origin 'http://localhost:3000' has been blocked by CORS policy
#react#cors#api#fetch#proxy

The Error

When you attempt to fetch data from an external API or a backend running on a different port than your React application, you likely encounter this specific error in your browser console:

Access to fetch at 'http://api.example.com' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

This error prevents your application from receiving data, often resulting in a failed network request even if the server actually processed the logic correctly.

Root Cause

CORS (Cross-Origin Resource Sharing) is a security mechanism implemented by browsers to prevent malicious websites from making requests to a different domain than the one that served the web page. In modern web development, your React app usually runs on http://localhost:3000 while your API might be on http://localhost:5000 or http://api.example.com. Because the domains or ports differ, the browser blocks the response unless the server explicitly gives permission.

Step-by-Step Fixes

Solution 1: Fix the Server (The Recommended Way)

The most robust way to solve CORS is to configure the backend server to allow requests from your React app's origin. You must add the Access-Control-Allow-Origin header to the server response.

Node.js / Express Example

Install the cors package:

npm install cors

Then, apply it as middleware in your server.js:

const express = require('express');
const cors = require('cors');
const app = express();

// Allow requests from your specific React dev server
app.use(cors({
  origin: 'http://localhost:3000'
}));

app.get('/api/data', (req, res) => {
  res.json({ message: 'Success' });
});

app.listen(5000);

Python / FastAPI Example

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

Solution 2: Use a Development Proxy (React Side)

If you don't have access to the backend code or want a quick fix for local development, you can use a proxy. This tells the React development server to forward requests to the API server, making the browser think the request is coming from the same origin.

For Create React App (CRA)

Open your package.json and add the proxy field at the bottom:

{
  "name": "my-react-app",
  "version": "0.1.0",
  "dependencies": { ... },
  "proxy": "http://localhost:5000"
}

After adding this, change your fetch calls from absolute URLs to relative paths:

// Change this:
fetch('http://localhost:5000/api/users')

// To this:
fetch('/api/users')

Note: You must restart your React development server for this change to take effect.

For Vite Projects

In vite.config.ts or vite.config.js, configure the server proxy:

export default defineConfig({
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:5000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      },
    },
  },
});

Solution 3: Setup a Manual Proxy Middleware

If you need more control (e.g., proxying to multiple backends), use http-proxy-middleware.

  • Install the package: npm install http-proxy-middleware
  • Create a file named src/setupProxy.js (No need to import it anywhere, CRA finds it automatically).
const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:5000',
      changeOrigin: true,
    })
  );
};

Verification Steps

  • Open your React application in Chrome or Firefox.
  • Press F12 to open Developer Tools and go to the Network tab.
  • Trigger the API call (e.g., refresh the page or click a button).
  • Click on the failed request.
  • Look at Response Headers. If the fix worked, you should see: Access-Control-Allow-Origin: http://localhost:3000 (or *).
  • Check the Console; the red CORS error should be gone.

Expert Tips

  • Avoid * in Production: While app.use(cors({ origin: '*' })) is easy for testing, it is insecure. Always specify your exact production domain.
  • Check the Protocol: http://localhost:3000 and https://localhost:3000 are considered different origins. Ensure they match.
  • Preflight Requests: For complex requests (like those with custom headers or PUT/DELETE methods), browsers send an OPTIONS request first. Ensure your server handles OPTIONS requests and returns the correct CORS headers.
  • Cookies and Credentials: If you need to send cookies or Authorization headers, you must set credentials: 'include' in your fetch options and allow_credentials=True on your server.

Related Error Notes