Handling CORS in Next.js API Routes
CORS isn't a global config; it's a per-route response header. To allow cross-origin requests to your API, you must manually set headers like `Access-Control-Allow-Origin` in your Route Handlers, including handling preflight OPTIONS requests.
WHY IT EXISTS: Browsers enforce the Same-Origin Policy, a security measure preventing scripts on one site from making requests to another. CORS (Cross-Origin Resource Sharing) is the standard mechanism for a server to relax this policy and explicitly permit requests from specific external origins.
THE MENTAL MODEL: Think of CORS as a bouncer for your API. By default, the bouncer only admits requests from the same origin (your app's domain). To let in requests from a different domain, you must explicitly add that domain to the guest list by setting specific response headers on a per-request basis.
HOW IT WORKS: In Next.js, you manage CORS by setting headers on the response object within your API Routes or Route Handlers. You are responsible for returning the correct headers, such as Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Allow-Headers. For requests that are not "simple" (e.g., using methods other than GET/POST/HEAD or including custom headers), the browser sends a preflight OPTIONS request first. You must create a handler for this OPTIONS method on the same route to approve the subsequent request.
WHEN TO USE IT: Use CORS when you intend for your API to be consumed by a browser-based client hosted on a different domain, subdomain, or port. This is common for public APIs or in a micro-frontend architecture where the frontend and backend are decoupled and deployed separately.
WHEN NOT TO USE IT: You don't need to configure CORS if your API is only ever called from your own frontend on the same domain or via server-to-server communication. The Same-Origin Policy doesn't apply in these cases. Over-exposing your API with a wildcard * origin is a security risk if the API is not meant to be fully public.
ONE CANONICAL EXAMPLE: To allow https://my-other-site.com to fetch data from your /api/items endpoint, your Route Handler (app/api/items/route.js) would include a GET handler that returns a NextResponse with the header 'Access-Control-Allow-Origin': 'https://my-other-site.com'. You would also need an OPTIONS handler in the same file that returns a 200 OK response with the appropriate Allow-Origin, Allow-Methods, and Allow-Headers headers to handle preflight checks from the browser.
Read the original → nextjs.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.