Next.jsCORSAPI RoutesBackend

Fix: Next.js API Route Blocked by CORS Policy

Stop cross-origin resource sharing errors from breaking your frontend integrations.

K

Khadar Baba

Senior Engineer

6 min read
Updated 5/20/2026
Urgency: High: Your fetch requests fail with 'Access to fetch at ... from origin ... has been blocked by CORS policy.'Tested against Next.js 14 & Firebase v10 • Last verified May 2026

You build an awesome Next.js API route under `app/api/data/route.ts` and test it with Postman — it works perfectly. But the moment you try to fetch it from a different origin, domain, or mobile app, the browser blocks it and throws an angry console error:

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

This is a CORS (Cross-Origin Resource Sharing) block. Browsers enforce this security mechanism to prevent unauthorized websites from accessing your endpoints. To allow access, your API must explicitly declare which origins are permitted.

TL;DR - Quick CORS Headers Fix

  • 1Are you calling a serverless function on a different domain without specifying headers?
  • 2Have you enabled preflight OPTIONS requests on your custom API endpoints?
  • 3Are you missing the Access-Control-Allow-Origin header in your response?

Root Causes

Missing Access-Control-Allow-Origin Header

Your serverless Next.js endpoint does not return the correct HTTP headers authorizing the client's domain to access the resources.

fetch('https://yoursite.com/api/data') // calls origin with no headers

Unconfigured OPTIONS Preflight Request

Browsers automatically send a preflight OPTIONS request before making complex requests (like POST with JSON content or custom headers). If your Next.js route returns a 405 or 404 for OPTIONS, the primary request is blocked.

export async function OPTIONS() { // Route must return status 200 with headers }

Incorrect Header Spelling or Syntax

Declaring multiple origins inside a single 'Access-Control-Allow-Origin' header (like 'origin1, origin2') or misspelling common terms will invalidate the browser policy validation.

Step-by-Step Fix Guide

1

Add Headers to Individual Route Handlers

For targeted APIs, set headers inside your route's Response constructor. Be sure to handle the preflight OPTIONS request.

import { NextResponse } from 'next/server';

const CORS_HEADERS = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type, Authorization',
};

export async function OPTIONS() {
  return NextResponse.json({}, { headers: CORS_HEADERS });
}

export async function GET() {
  return NextResponse.json({ success: true }, { headers: CORS_HEADERS });
}
2

Configure Global CORS in next.config.mjs

If you want all API routes to automatically support CORS without modifying individual files, define headers in your next.config configuration.

const nextConfig = {
  async headers() {
    return [
      {
        source: '/api/:path*',
        headers: [
          { key: 'Access-Control-Allow-Credentials', value: 'true' },
          { key: 'Access-Control-Allow-Origin', value: '*' },
          { key: 'Access-Control-Allow-Methods', value: 'GET,DELETE,PATCH,POST,PUT,OPTIONS' },
          { key: 'Access-Control-Allow-Headers', value: 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, Authorization' },
        ]
      }
    ]
  }
};
3

Use Middleware for Dynamic Allowed Origins

If you need to dynamically check if the requesting origin is on an approved list (rather than using wildcard '*'), configure it in middleware.

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

const ALLOWED_ORIGINS = ['https://myapp.com', 'https://admin.myapp.com'];

export function middleware(req: NextRequest) {
  const origin = req.headers.get('origin');
  const response = NextResponse.next();
  
  if (origin && ALLOWED_ORIGINS.includes(origin)) {
    response.headers.set('Access-Control-Allow-Origin', origin);
  }
  
  return response;
}

Stuck on CORS or API Integration Issues?

Configuring secure cross-origin headers or middleware filters can be tedious. I can configure your Next.js route security to prevent blocks.

Get API Rescue Help

Related Errors

  • Access-Control-Allow-Origin cannot contain wildcard when credentials mode is include.

    If credentials (like cookies or authentication headers) are needed, you must set Access-Control-Allow-Origin to the specific requesting origin value rather than '*'

Prevention Strategy

  • Always define an OPTIONS handler for complex endpoints.
  • Do not use wildcards '*' in production environments if cookies or session authorization headers are transmitted.
  • Keep cors headers centralized inside next.config.mjs or middleware.ts to avoid code duplication errors.

Still Stuck With This Issue?

Send your exact error message or deployment issue. I'll respond with a targeted fix.

Drop screenshots here or browse

PNG, JPG, WebP • Max 5MB • Up to 3 files

Private submission — your data is never shared publicly.

Need a Deeper Fix?

Describe your full project issue below and I'll get back to you with a targeted fix.

Drop screenshots here or browse

PNG, JPG, WebP • Max 5MB • Up to 3 files

Your data is stored securely and never shared with third parties.

Frequently Asked Questions about Fix CORS Errors in Next.js API Routes | Header configuration Guide

Why does Postman work but the browser fails?

Quick Answer: CORS is a browser-only security feature. Postman is a backend tool that executes HTTP requests directly, bypassing origin restrictions. The browser blocks the response after receiving it if the CORS headers are missing.

ServicesStudent ProjectsBlogContact
Chat with an Expert