[▲ Vercel Community](/) · [Categories](/categories) · [Latest](/latest) · [Top](/top) · [Live](/live) [Discussions](/c/community/4) # Different ways to handle CORS on Vercel 1206 views · 8 likes · 2 posts Anshuman Bhardwaj (@anshumanb) · 2025-01-31 · ♥ 6 Cross-Origin Resource Sharing ([CORS](https://developer.mozilla.org/en-US/docs/Glossary/CORS)) issues are common when you are hosting your backend and frontend applications on different [origins](https://developer.mozilla.org/en-US/docs/Glossary/Origin). Browsers implement the CORS mechanism as a safeguard to prevent applications on a different origin from loading your resources. This is why it is important to set up your backend application with the correct CORS configuration. ## Getting Started --- When using Vercel, you can configure CORS headers in the following ways: - Using the Vercel project configuration - Using the Edge Middleware - Using framework configuration - Route handler configuration > This post uses the code snippets from the [cors-example GitHub repository](https://github.com/vercel-support/cors-examples), which showcases working examples of CORS configuration in popular web frameworks such as Next.js, Nuxt, Astro, and Flask deployed on Vercel. > ### Using the Vercel project configuration You can use the [headers](https://vercel.com/docs/projects/project-configuration#headers) configuration option in the `vercel.json` file of your project to add CORS headers. For example, the following configuration will add the CORS headers to all responses from the `/vercel-config-cors` endpoint. ```jsx { "headers": [ { "source": "/vercel-config-cors", "headers": [ { "key": "Access-Control-Allow-Origin", "value": "https://rrv7.vercel.app" }, { "key": "Access-Control-Allow-Methods", "value": "GET, POST, PUT, DELETE, OPTIONS" }, { "key": "Access-Control-Allow-Headers", "value": "Content-Type, Authorization" } ] } ] } ``` ### Using the Edge Middleware The [Edge Middleware](https://vercel.com/docs/functions/edge-middleware) provides a fast and efficient way to modify headers on the requests and responses of your applications. For example, the [middleware.ts](https://github.com/vercel-support/cors-examples/blob/main/astro-app/middleware.ts) from an Astro project adds the appropriate CORS headers to the requests coming to the `/mw-cors` endpoint without changing the endpoint handler code. To view the complete code, see this [GitHub repository](https://github.com/vercel-support/cors-examples/blob/main/astro-app/middleware.ts). ```jsx import { next } from "@vercel/edge"; const allowedOrigins = ["https://rrv7.vercel.app"]; const corsOptions = { "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS", "Access-Control-Allow-Headers": "Content-Type, Authorization", }; export default function middleware(request: Request) { // Check the origin from the request const origin = request.headers.get("origin") ?? ""; const isAllowedOrigin = allowedOrigins.includes(origin); // Handle preflighted requests const isPreflight = request.method === "OPTIONS"; if (isPreflight) { const preflightHeaders = { ...(isAllowedOrigin && { "Access-Control-Allow-Origin": origin }), ...corsOptions, }; return Response.json({ preflight: true }, { headers: preflightHeaders }); } // Handle simple requests const response = new Response(); if (isAllowedOrigin) { response.headers.set("Access-Control-Allow-Origin", origin); } Object.entries(corsOptions).forEach(([key, value]) => { response.headers.set(key, value); }); return next(response); } export const config = { matcher: "/mw-cors", }; ``` ### Using framework configuration Many frameworks such as [Next.js](https://nextjs.org/) and [Nuxt](http://nuxt.com/) provide easy APIs to add CORS headers from the config file. For example, the following [nuxt.config.ts](https://github.com/vercel-support/cors-examples/blob/main/nuxt-app/nuxt.config.ts) sets `routeRules` for a specific route (`/api/nuxt-config-cors`) to send the CORS headers automatically for all the requests made to this endpoint. ```jsx export default defineNuxtConfig({ compatibilityDate: "2024-11-01", devtools: { enabled: true }, routeRules: { "/api/nuxt-config-cors": { headers: { "Access-Control-Allow-Origin": "https://rrv7.vercel.app", "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS", "Access-Control-Allow-Headers": "Content-Type, Authorization", }, }, }, }); ``` ### Route handler configuration At last, you can always return the CORS headers from the route handler response. For example, the following [Next.js route handler](https://github.com/vercel-support/cors-examples/blob/main/nextjs-app/src/app/api/route.ts) adds the headers to the endpoint response. ```tsx export async function GET() { return new Response("Hello, Next.js!", { status: 200, headers: { "Access-Control-Allow-Origin": "https://rrv7.vercel.app", "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS", "Access-Control-Allow-Headers": "Content-Type, Authorization, X-Custom-Header", }, }); } ``` ## Troubleshooting common issues --- ### Incorrect allow origin header The [Access-Control-Allow-Origin](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin) lets the server define which origin is allowed to send a cross-origin request. It is important to ensure that the [origin](https://developer.mozilla.org/en-US/docs/Glossary/Origin) value must matches all three aspects: scheme, hostname, and port of the incoming request’s `Origin` header. ### Incorrect HTTP methods The [Access-Control-Allow-Methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods) header tells the browser about the HTTP methods that the server supports. For example, it can become an issue when your frontend application is making an HTTP request that triggers a [Preflight request](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request) and you don’t support the `OPTIONS` request method, which is used by browsers to check if CORS is supported. ### Missing allowed headers It’s common to overlook the additional headers or custom headers that your frontend application might be sending along with the requests to your backend. The [Access-Control-Allow-Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers) header lets your server define a list of headers that are allowed for cross-origin requests. ### Missing credentials header By default, CORS doesn’t allow `cookies` with cross-origin requests, which will lead to errors in your application. To allow credentials to be sent with your requests you need to: 1. Allow credentials on CORS in your server code by sending the [Access-Control-Allow-Credentials](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials) header. For example, the following Flask application specifies `supports_credentials=True` to allow sending credentials. ```python from flask import Flask from flask_cors import CORS app = Flask(__name__) CORS(app, supports_credentials=True, resources={r"/api/cors": {"origins": "https://rrv7.vercel.app"}}) ``` 2. Update your `fetch` call to include `credentials` with the request, as follows: ```tsx const response = await fetch(url, { method: 'GET', credentials: 'include', // This tells fetch to include credentials headers: { 'Content-Type': 'application/json', } }); ``` ## Resources --- - https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS - https://github.com/vercel-support/cors-examples - https://github.com/vercel-support/express-vercel Pauline P. Narvas (@pawlean) · 2025-04-23 · ♥ 2 Spotted this in the wild too! Sharing in case it's helpful → https://dev.to/nurulislamrimon/resolving-cors-errors-in-a-nestjs-app-deployed-on-vercel-jb