-2

I'm trying to consume my own Node.js/Express API from a frontend application, but I'm getting a CORS error that I couldn't solve.

Context:

  • Backend: Node.js + Express
  • Deployment: Vercel (@vercel/node)
  • Frontend: hosted on https://www.linkgrid.site
  • API URL: https://linkgrid-api.vercel.app/api/users/create

The error I get

Access to XMLHttpRequest at 'https://linkgrid-api.vercel.app/api/users/create' from origin 'https://www.linkgrid.site' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I have:

  • Configured cors middleware on Express.
  • Added CORS-related headers in vercel.json.
  • Tried different combinations of allowed origins and headers.
  • Confirmed that both frontend and backend are correctly deployed.

vercel.json:

{
  "version": 2,
  "builds": [
    {
      "src": "dist/server.js",
      "use": "@vercel/node",
      "config": { "includeFiles": ["dist/**"] }
    }
  ],
  "routes": [
    {
      "src": "/(.*)",
      "dest": "dist/server.js",
      "headers": {
        "Access-Control-Allow-Origin": "https://linkgrid.site",
        "Access-Control-Allow-Methods": "GET,POST,PUT,DELETE,OPTIONS,PATCH",
        "Access-Control-Allow-Headers": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, Authorization",
        "Access-Control-Allow-Credentials": "true",
        "Access-Control-Max-Age": "86400"
      }
    }
  ]
}

app.ts:

export const app = express();

app.use(
  cors({
    origin: [
      "https://linkgrid.site",
      "https://www.linkgrid.site",
      "https://linkgrid.vercel.app",
      ...(process.env.NODE_ENV === "development" ? ["http://localhost:3000"] : []),
    ],
    methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"],
    allowedHeaders: [
      "Content-Type",
      "Authorization",
      "X-Requested-With",
      "Accept",
      "Origin"
    ],
    exposedHeaders: ["Content-Range", "X-Content-Range"],
    credentials: true,
    maxAge: 86400,
    preflightContinue: false,
    optionsSuccessStatus: 204
  })
);

app.options("*", cors());

app.use(
  helmet({
    crossOriginResourcePolicy: { policy: "cross-origin" },
    crossOriginOpenerPolicy: { policy: "same-origin" }
  })
);

app.use(express.json());
app.use(limiter);

app.use("/api/users", userRouter);
app.use("/api/links", linkRouter);

app.use(errorMiddleware);

Even after configuring both cors in Express and setting the proper CORS headers in vercel.json, why am I still getting this preflight CORS error? Both backend and Vercel config seem correct to me.

1
  • This question is similar to: How to enable CORS not working on vercel?. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. Commented May 28 at 8:01

1 Answer 1

1

Your Express CORS config already includes https://www.linkgrid.site, which is correct. However, the vercel static headers are overriding your Express CORS middleware.

Remove them, and just use:

{
  "version": 2,
  "builds": [
    {
      "src": "dist/server.js",
      "use": "@vercel/node",
      "config": { "includeFiles": ["dist/**"] }
    }
  ],
  "routes": [
    {
      "src": "/(.*)",
      "dest": "dist/server.js"
    }
  ]
}

You can also update your vercel configuration to include (www), which is what was missing:

"Access-Control-Allow-Origin": "https://www.linkgrid.site",

But, it's always nice to have definitions defined in one place to reduce issues like this and potential conflicts.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your response! I actually tried removing the static headers from vercel.json and relied only on the Express CORS config, as you suggested. But unfortunately, the CORS preflight error still persists. Do you think this could be related to some kind of Vercel cache during redeploy? Or is there any other potential reason why the CORS headers wouldn't be properly applied in this scenario? Any further insights would be much appreciated!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.