Skip to content
API20-30 min

CORS Setup Implementation

This guide explains origin allowlists, credentials, preflight handling, local dev URLs, production domains, and common CORS mistakes.

Node.jsExpressBrowser APIs

Prerequisites

  • A frontend URL and backend URL that may be on different origins.
  • An Express API.
  • A list of production domains allowed to call your API.
  • Knowledge of whether your auth uses cookies or Authorization headers.
1

Install CORS middleware

Implementation snippet
npm install cors
npm install -D @types/cors
2

Create an origin allowlist

Implementation snippet
const allowedOrigins = [
  "http://localhost:5173",
  "http://localhost:3000",
  "https://app.example.com",
];
3

Configure CORS

  1. Allow requests with no origin for server-to-server tools if needed.
  2. Allow only known frontend origins.
  3. Enable credentials only when using cookies or HTTP auth.
  4. List required headers and methods explicitly for predictable preflight behavior.
Implementation snippet
import cors from "cors";

app.use(cors({
  origin(origin, callback) {
    if (!origin || allowedOrigins.includes(origin)) return callback(null, true);
    callback(new Error("Not allowed by CORS"));
  },
  credentials: true,
  methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
  allowedHeaders: ["Content-Type", "Authorization"],
}));
4

Call the API from the frontend

Implementation snippet
await fetch("https://api.example.com/api/me", {
  credentials: "include",
  headers: { Authorization: `Bearer ${accessToken}` },
});
Note: Use `credentials: "include"` only when cookies are part of the auth flow.
5

Common mistakes

Checklist
  • Do not use `origin: *` with `credentials: true`.
  • Do not forget localhost ports during local development.
  • Do not rely on CORS as backend authorization.
  • Do not add every domain dynamically without validation.
6

Verify CORS

  1. Open the frontend on the allowed origin and call a protected endpoint.
  2. Confirm OPTIONS preflight returns 204 or 200.
  3. Try the same request from an unlisted origin and confirm it fails.
  4. Check cookie auth in a production-like HTTPS environment.

Need implementation help?

Want this built correctly in your codebase?

Send us your stack, repo context, and the feature you need. We will help you implement it cleanly and hand over the working code.

Free scoping callFixed timelineFull source ownership
Get implementation help