Next.js API Route CORS Error Fix
In this tutorial, you'll learn about Next.js API Route CORS Error Fix. We cover key concepts, practical examples, and best practices.
The Problem
Browser requests to a Next.js API route fail with CORS Missing Allow Origin or CORS Preflight Did Not Succeed. Next.js API routes do not include CORS headers by default.
Quick Fix
Step 1: Add CORS headers to the API response
// Wrong — no CORS headers
export default function handler(req, res) {
res.status(200).json({ message: 'OK' });
}
// Right
export default function handler(req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.status(200).json({ message: 'OK' });
}
Expected output: The browser accepts the response from any origin.
Step 2: Handle OPTIONS preflight requests
export default function handler(req, res) {
// Handle CORS preflight
if (req.method === 'OPTIONS') {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
return res.status(200).end();
}
// Handle actual request
res.setHeader('Access-Control-Allow-Origin', '*');
res.status(200).json({ message: 'OK' });
}
Expected output: The preflight OPTIONS request returns 200 with CORS headers.
Step 3: Use a CORS middleware
// lib/cors.js
export function cors(req, res) {
const origin = req.headers.origin;
const allowedOrigins = [
'https://example.com',
'http://localhost:3000',
];
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
}
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
}
// pages/api/hello.js
import { cors } from '@/lib/cors';
export default function handler(req, res) {
cors(req, res);
if (req.method === 'OPTIONS') {
return res.status(200).end();
}
res.status(200).json({ message: 'OK' });
}
Expected output: CORS headers are set consistently across all API routes.
Step 4: Use environment-specific origins
export function cors(req, res) {
const allowedOrigins = process.env.CORS_ORIGINS
? process.env.CORS_ORIGINS.split(',')
: ['http://localhost:3000'];
const origin = req.headers.origin;
if (allowedOrigins.includes(origin) || allowedOrigins.includes('*')) {
res.setHeader('Access-Control-Allow-Origin', origin);
}
}
Expected output: Allowed origins are configurable per environment.
Step 5: Apply CORS to all API routes with a wrapper
// lib/withCors.js
export function withCors(handler) {
return (req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
if (req.method === 'OPTIONS') {
return res.status(200).end();
}
return handler(req, res);
};
}
// pages/api/hello.js
export default withCors(function handler(req, res) {
res.status(200).json({ message: 'OK' });
});
Expected output: Every wrapped API route includes CORS headers automatically.
Prevention
- Add CORS headers to all API routes that are called from different origins
- Handle OPTIONS preflight requests explicitly
- Restrict
Access-Control-Allow-Originto specific domains in production - Use a middleware pattern to avoid duplicating CORS logic
Common Mistakes with api cors
- Using
returnto exit a function early instead of wrapping a pure value in the monad - Mixing let bindings with <- bindings in do notation, producing type errors
- Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
These mistakes appear frequently in real-world NEXTJS code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro