Skip to content

cors-middleware ​

The cors middleware handles Cross-Origin Resource Sharing (CORS) by setting the appropriate response headers. This is required when your API is accessed from a different domain than the one serving it.

Installation ​

The CORS middleware is included with Remix. No additional installation is needed.

Import ​

ts
import { cors } from 'remix/cors-middleware'

API ​

cors(options?) ​

Returns a middleware function that sets CORS headers on responses and handles preflight requests.

ts
let router = createRouter({
  middleware: [
    cors({
      origin: 'https://myapp.com',
    }),
  ],
})

Options ​

OptionTypeDefaultDescription
originstring | string[] | boolean | (origin: string) => string | falsefalseConfigures the Access-Control-Allow-Origin header. See Origin Configuration below.
methodsstring[]['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE']Allowed HTTP methods. Sets the Access-Control-Allow-Methods header.
allowedHeadersstring[]Reflects request headersHeaders the client is allowed to send. Sets the Access-Control-Allow-Headers header.
exposedHeadersstring[][]Headers the client is allowed to read from the response. Sets the Access-Control-Expose-Headers header.
credentialsbooleanfalseWhether to include the Access-Control-Allow-Credentials: true header. Required for cookies and HTTP authentication.
maxAgenumberundefinedHow long (in seconds) the browser should cache the preflight response. Sets the Access-Control-Max-Age header.

Origin Configuration ​

The origin option supports several formats:

Boolean ​

  • true --- Reflects the request's Origin header (allows any origin).
  • false --- Disables CORS headers entirely.

String ​

A single allowed origin:

ts
cors({ origin: 'https://myapp.com' })

Use '*' to allow all origins (cannot be combined with credentials: true).

Array ​

Multiple allowed origins:

ts
cors({ origin: ['https://myapp.com', 'https://admin.myapp.com'] })

Function ​

A function that receives the request's Origin header and returns an allowed origin string, or false to deny:

ts
cors({
  origin(requestOrigin) {
    if (requestOrigin?.endsWith('.myapp.com')) {
      return requestOrigin
    }
    return false
  },
})

Preflight Handling ​

When a browser sends a preflight request (an OPTIONS request with Access-Control-Request-Method), the middleware:

  1. Responds with the configured CORS headers.
  2. Returns a 204 No Content response immediately, without calling downstream middleware or the route handler.

This means preflight requests are fast and do not hit your application logic.

Examples ​

Allow All Origins (Public API) ​

ts
cors({
  origin: '*',
  methods: ['GET', 'POST'],
  allowedHeaders: ['Content-Type'],
})

Specific Origins with Credentials ​

ts
cors({
  origin: ['https://myapp.com', 'https://admin.myapp.com'],
  credentials: true,
  maxAge: 86400,
})

Never use origin: '*' with credentials

Setting origin: '*' with credentials: true is not allowed by browsers and will cause requests to fail. If you need cookies or HTTP authentication, specify exact origins.

Dynamic Origins ​

For multi-tenant applications or many subdomains:

ts
cors({
  origin(requestOrigin) {
    // Look up allowed origins from a database or config
    let allowedOrigins = getAllowedOrigins()
    if (requestOrigin && allowedOrigins.includes(requestOrigin)) {
      return requestOrigin
    }
    return false
  },
  credentials: true,
})

Expose Custom Headers ​

Allow the client to read custom response headers:

ts
cors({
  origin: 'https://myapp.com',
  exposedHeaders: ['X-Total-Count', 'X-Request-Id'],
})

Released under the MIT License.