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.