1

I am trying to create an application with supabase as DB, vercel backend (url: http://localhost:3000/api/) and netlify frontend (url: http://localhost:5173). The frontend is a react application with vite and the backend is a list of serverless functions with express.

The problem is when I try to make a request from the frontend I get the 500 error CORS Preflight Did Not Succeed. That happens when I add the CORS headers to vercel according to documentation.

I have also tried to use the cors middleware from npm and add the headers the express way but for some reason the headers are not send (I also don't seem to be able to change any header this way).

Any help would be greatly appreciated.

vercel.json:

{
  "headers": [
    {
      "source": "/api/(.*)",
      "headers": [
        { "key": "Access-Control-Allow-Credentials", "value": "true" },
        { "key": "Access-Control-Allow-Origin", "value": "http://localhost:5173" },
        { "key": "Access-Control-Allow-Methods", "value": "GET,OPTIONS,PATCH,DELETE,POST,PUT" },
        { "key": "Access-Control-Allow-Headers", "value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" }
      ]
    }
  ]
}


This is the create app function which I use to initialize all the functions so I don't write the same parameters for all the functions.

import express, { NextFunction, Request, Response, json } from "express"
import helmet from "helmet"
import cors from "cors"
import cookieParser from "cookie-parser"

export function createApp() {
    const app = express()
    app.use(customCorsMiddleware)
    app.use(cookieParser())
    app.use(helmet())
    app.use(json())
    const url = process.env.CORS_URL
    const middle = cors({ origin: true, credentials: true,}) 
    app.use(middle)
    return app
}
Azzarian
  • 153
  • 2
  • 13

1 Answers1

0

Looking at "How can I enable CORS on Vercel?", I am intrigued by "[How to enable CORS not working on vercel?]"(How to enable CORS not working on vercel?) which says:

Turns out Vercel overwrites the cors settings you put anywhere outside the json. It is not possible to mix a headers array and routes array in the same file. But you can just put a header inside the routes.

That suggests that if you are using the routes array to define your routes in vercel.json, then you should place the CORS headers there, rather than in a separate headers array in the same file. Doing so would ensure that Vercel does not override your CORS settings.

In the context of your vercel.json, this means you should move the CORS-related headers inside the routes definition.

So instead of defining your headers like this:

{
  "headers": [
    // your CORS headers here
  ]
}

You would include them within the routes array:

{
  "version": 2,
  "builds": [
    {
      "src": "./index.js",
      "use": "@vercel/node"
    }
  ],
  "routes": [
    {
      "src": "/api/(.*)",
      "dest": "./index.js",
      "methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
      "headers": {
        "Access-Control-Allow-Origin": "http://localhost:5173",
        "Access-Control-Allow-Methods": "GET,POST,PUT,DELETE,PATCH,OPTIONS",
        "Access-Control-Allow-Headers": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version",
        "Access-Control-Allow-Credentials": "true"
      }
    }
  ]
}

By doing this, you would adhere to Vercel's specific requirements for CORS settings, which should prevent any overriding or conflict with your Express middleware settings.

If Vercel's vercel.json CORS configuration is effectively managing CORS for your application when deployed, then applying CORS settings again in your Express middleware might be redundant. In that scenario, conditionally applying CORS middleware only during local development makes sense.

For local testing, having CORS set up in your middleware would be beneficial when you are running your server locally for testing, particularly when your frontend is also running locally on a different port.
Using conditional logic for CORS middleware in Express makes your code more flexible and adaptable for different environments (local vs production).

You could conditionally apply it for development:

if (process.env.NODE_ENV === 'development') {
  const middle = cors({ origin: true, credentials: true });
  app.use(middle);
}

If Vercel's CORS settings meet all your requirements, then you may not need to include CORS middleware in your Express setup when deployed. Conditionally applying it for local development ensures that you have a consistent development experience without affecting your production environment.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250