Fix CORS in Next.js
Last updated: April 2026
Browser Console Error
Access to fetch at 'https://api.yoursite.com/api/data' from origin 'https://yourapp.com'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present.
Next.js API routes and App Router route handlers need CORS headers set explicitly. There is no global CORS config โ set headers in each handler or use middleware.
Test your Next.js CORS live โApp Router โ route.ts handler
// app/api/data/route.ts
import { NextRequest, NextResponse } from 'next/server';
const corsHeaders = {
'Access-Control-Allow-Origin': 'https://yourapp.com',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
};
export async function OPTIONS() {
return NextResponse.json({}, { headers: corsHeaders });
}
export async function GET(req: NextRequest) {
const data = { message: 'ok' };
return NextResponse.json(data, { headers: corsHeaders });
}
Pages Router โ API route (pages/api/data.ts)
import type { NextApiRequest, NextApiResponse } from 'next';
export default function handler(req: NextApiRequest, res: NextApiResponse) {
res.setHeader('Access-Control-Allow-Origin', 'https://yourapp.com');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
if (req.method === 'OPTIONS') {
res.status(204).end();
return;
}
res.status(200).json({ message: 'ok' });
}
Middleware โ apply CORS to all API routes
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
export function middleware(req: NextRequest) {
const origin = req.headers.get('origin') ?? '';
const allowed = ['https://yourapp.com', 'http://localhost:5173'];
const res = NextResponse.next();
if (allowed.includes(origin)) {
res.headers.set('Access-Control-Allow-Origin', origin);
res.headers.set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.headers.set('Access-Control-Allow-Credentials', 'true');
}
if (req.method === 'OPTIONS') {
return new NextResponse(null, { status: 204, headers: res.headers });
}
return res;
}
export const config = {
matcher: '/api/:path*',
};
vercel.json โ headers for static CORS
{
"headers": [
{
"source": "/api/(.*)",
"headers": [
{ "key": "Access-Control-Allow-Origin", "value": "https://yourapp.com" },
{ "key": "Access-Control-Allow-Methods", "value": "GET, POST, OPTIONS" },
{ "key": "Access-Control-Allow-Headers", "value": "Content-Type" }
]
}
]
}