fastasy-logo

CORS in NextJS: Complete Guide to Fix your Errors (2025)

CORS in NextJS
Mostafa
Written by MostafaAuthor
2025-03-07

Ever been blocked by a CORS error while building your NextJS app? You're not alone. CORS issues in NextJS are like that friend who shows up uninvited to your party—frustrating but ultimately there for your own good.

I remember building my first NextJS project thinking everything would just work. Then boom—CORS errors everywhere. My API requests were failing, my data wasn't loading, and I was questioning my life choices.

Let's fix your CORS nextjs problems once and for all.

Configuring CORS NextJS Globally with next.config.js Headers

Setting up CORS in your NextJS project doesn't have to be a nightmare. The simplest approach? Configure it globally using your next.config.js file.

next.config.js
javascript
// next.config.js
module.exports = {
  async headers() {
    return [
      {
        // Apply these headers to all routes
        source: '/(.*)',
        headers: [
          {
            key: 'Access-Control-Allow-Origin',
            value: '*', // Be more restrictive in production
          },
          {
            key: 'Access-Control-Allow-Methods',
            value: 'GET,OPTIONS,PATCH,DELETE,POST,PUT',
          },
          {
            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',
          },
        ],
      },
    ];
  },
};

This approach works great for simple projects, but when you need more control, middleware is your best friend.

Dynamic CORS Policies in NextJS Using Middleware

NextJS 12+ introduced middleware, giving us superpowers for handling CORS dynamically.

middleware.js
// middleware.js
import { NextResponse } from 'next/server';

export function middleware(request) {
  // Get the origin from the request
  const origin = request.headers.get('origin') || '';
  
  // Define allowed origins (you could load these from env variables)
  const allowedOrigins = [
    'https://yourdomain.com',
    'https://app.yourdomain.com',
    'http://localhost:3000',
  ];
  
  // Check if the origin is allowed
  const isAllowedOrigin = allowedOrigins.includes(origin);
  
  // Create the response
  const response = NextResponse.next();
  
  // Set CORS headers conditionally
  if (isAllowedOrigin) {
    response.headers.set('Access-Control-Allow-Origin', origin);
    response.headers.set('Access-Control-Allow-Credentials', 'true');
    response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  }
  
  // Handle OPTIONS request (preflight)
  if (request.method === 'OPTIONS') {
    return new NextResponse(null, { 
      status: 204,
      headers: response.headers
    });
  }
  
  return response;
}

// Only run the middleware on API routes
export const config = {
  matcher: '/api/:path*',
};

This middleware approach gives you fine-grained control over your CORS policies. I've used this pattern on multiple projects, and it's been rock solid.

Advanced CORS NextJS Strategies: Whitelisting Origins and Credentials

When you're building more complex applications, you'll need more sophisticated CORS strategies.

Here's what I do for production apps that need tight security:

javascript
// Environment variables approach
// .env.local
ALLOWED_ORIGINS=https://app.example.com,https://admin.example.com

// middleware.js or api handler
const allowedOrigins = process.env.ALLOWED_ORIGINS.split(',');

This way, you can manage your whitelist through environment variables without hardcoding them.

For handling credentials properly:

// Remember to set these headers
response.headers.set('Access-Control-Allow-Credentials', 'true');

And on your frontend:

fetch('https://api.example.com/data', {
  credentials: 'include' // This sends cookies
})

Deploying CORS NextJS Apps on Vercel: Best Practices

Deploying to Vercel? Here's what you need to know about CORS nextjs on their platform:

  1. Vercel respects your next.config.js headers configuration
  2. Environment variables work seamlessly for dynamic origins
  3. Preview deployments need special attention for CORS:
// Dynamically handle Vercel preview deployments
const vercelEnv = process.env.VERCEL_ENV;
let allowedOrigins = ['https://yourdomain.com'];

if (vercelEnv === 'preview') {
  // Allow Vercel preview URLs
  allowedOrigins.push(/.*\.vercel\.app$/);
}

I've spent hours debugging CORS issues on Vercel only to realize my preview environments needed different settings.

Resolving Common CORS NextJS Errors During Development

The most common CORS error you'll see is:

🚨 Access to fetch at 'http://localhost:3000/api/data' from origin 'http://localhost:3001' has been blocked by CORS policy 🚨

To fix CORS nextjs errors during development:

  1. Make sure your development server has CORS enabled:
// pages/api/your-endpoint.js
export default function handler(req, res) {
  // Enable CORS for development
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
  
  // Handle OPTIONS request
  if (req.method === 'OPTIONS') {
    return res.status(200).end();
  }
  
  // Your actual handler code
  // ...
}

2. Use a CORS proxy for external APIs during development:

// Instead of fetching directly
// const data = await fetch('https://external-api.com/data');

// Use your API route as a proxy
const data = await fetch('/api/proxy/external-api');

// Then in pages/api/proxy/external-api.js
export default async function handler(req, res) {
  const response = await fetch('https://external-api.com/data');
  const data = await response.json();
  res.status(200).json(data);
}

This proxy approach has saved me countless headaches when dealing with third-party APIs.

CORS NextJS and Authentication: Securing Cookies and Tokens

When dealing with authentication and CORS, you need to be extra careful:

// For token-based auth, you typically need these CORS headers
res.setHeader('Access-Control-Allow-Origin', 'https://yourdomain.com');
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Access-Control-Allow-Headers', 'Authorization');

For secure cookie handling:

// Setting secure cookies that work across domains
res.setHeader('Set-Cookie', [
  `token=${token}; HttpOnly; Secure; SameSite=None; Path=/; Max-Age=${60 * 60 * 24 * 7}`
]);

This setup works for most auth systems I've built, but remember that SameSite=None requires Secure to be set as well.

Optimizing CORS NextJS for SEO and Crawler Accessibility

Search engines need to access your APIs? Make sure your CORS settings allow it:

// Handle user agents for crawlers
const userAgent = req.headers['user-agent'] || '';
const isCrawler = /googlebot|bingbot|baiduspider/i.test(userAgent);

if (isCrawler) {
  // Allow access for search engine crawlers
  res.setHeader('Access-Control-Allow-Origin', '*');
}

This helps ensure that search engines can properly index your dynamic content.

CORS NextJS vs Alternative Frameworks

How does NextJS handle CORS compared to other frameworks?

NextJS vs Express:

  • NextJS has built-in API routes with simpler CORS configuration
  • Express gives more middleware flexibility but requires more setup

NextJS vs NestJS:

  • NestJS has a built-in @Cors() decorator
  • NextJS requires manual configuration

NextJS vs Remix:

  • Remix handles CORS through its loader/action system
  • NextJS uses API routes or middleware

In terms of performance, NextJS's middleware approach is extremely efficient as it runs before the request is fully processed.

The Future of CORS NextJS: New Features and Updates

NextJS 15 introduced some improvements for CORS handling:

next.config.js
// next.config.js in NextJS 15
module.exports = {
  async headers() {
    return [
      {
        source: '/api/:path*',
        headers: [
          { key: 'Access-Control-Allow-Origin', value: '*' },
          // Other headers
        ],
      },
    ];
  },
}

To enable CORS next js 15 properly, you can also use the new middleware capabilities:

middleware.ts
// middleware.ts in NextJS 15
export default function middleware(request) {
  const response = NextResponse.next();
  
  // You can now use new response header manipulation methods
  response.headers.set('Access-Control-Allow-Origin', '*');
  
  return response;
}

The new app router in NextJS also changes how we handle CORS:

app/api/route.js
// app/api/route.js
export async function GET(request) {
  const response = new Response(JSON.stringify({ message: 'Hello' }));
  
  // Set CORS headers
  response.headers.set('Access-Control-Allow-Origin', '*');
  
  return response;
}

export async function OPTIONS(request) {
  const response = new Response(null, { status: 204 });
  
  response.headers.set('Access-Control-Allow-Origin', '*');
  response.headers.set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
  response.headers.set('Access-Control-Allow-Headers', 'Content-Type');
  
  return response;
}

Stay updated on the NextJS docs for future CORS improvements.

Implementing proper CORS in NextJS isn't just about fixing errors—it's about building secure, robust applications. Follow these patterns, and you'll save yourself hours of debugging and security headaches.

Remember: CORS nextjs isn't your enemy—it's your app's security guard. Treat it with respect, configure it properly, and it'll keep your users safe while letting legitimate requests through.

Hi! 👋🏻 Need a website for your business?

Your Current Website 🐌 😞
  • Slow Loading Speed
  • Hard to Use on Phones
  • Confusing Layout
  • Messy Design
  • Not Secure
  • Doesn't show on Google
  • Can't edit Website Content
Fastazy Websites 🚀 😍
  • Quick to Load
  • Mobile Friendly
  • Easy Navigation
  • Clean and Organized
  • Secure and Safe
  • Easy to Find on Google (SEO)
  • Easy to edit Website Content
developementImg

What are you waiting for?

Get a website that looks great and lets you update content easily no coding needed! Grow your business online with Fastasy

Get started