My mobile web app on another domain calls my Next.js API and the browser blocks it with 'No Access-Control-Allow-Origin header'. How do I add CORS properly, including the preflight OPTIONS request?
DEV3 Developer Forum
How do I enable CORS for a Next.js route handler?
Ask a question
Every post is reviewed first. Usually reviewed within 24 hours.
dev3 ·
0
1 reply
dev3 · Accepted answer
Browsers send a preflight OPTIONS request for non-simple requests (JSON body, custom headers, Authorization). Your handler must answer it and add CORS headers to real responses.
// app/api/public/route.ts
const ALLOWED = new Set(["https://app.example.com", "https://www.example.com"]);
function corsHeaders(origin: string | null) {
const h: Record<string, string> = {
"Access-Control-Allow-Methods": "GET,POST,OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Max-Age": "86400",
Vary: "Origin",
};
if (origin && ALLOWED.has(origin)) h["Access-Control-Allow-Origin"] = origin;
return h;
}
export async function OPTIONS(req: Request) {
return new Response(null, { status: 204, headers: corsHeaders(req.headers.get("origin")) });
}
export async function GET(req: Request) {
return Response.json({ ok: true }, { headers: corsHeaders(req.headers.get("origin")) });
}
Whole-API alternative
next.config.ts headers() can attach static CORS headers to /api/:path*, but it cannot echo the request origin dynamically, so it suits a single fixed origin.
Rules
- Echo back a specific allowed origin.
*cannot be combined with credentials (cookies). - With cookies, also send
Access-Control-Allow-Credentials: trueand usecredentials: "include"on the client. - Add
Vary: Originwhen the value depends on the request. - A middleware/proxy can answer preflight for many routes in one place.
- CORS only protects browsers. Server-to-server calls ignore it, so keep real authentication.
Pitfall: errors thrown before your headers are added (for example a 500) show up as a CORS error in the browser, hiding the real cause. Check the Network tab.
You can test headers with the CORS checker.
0