> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/honojs/hono/llms.txt
> Use this file to discover all available pages before exploring further.

# cors

> API reference for the CORS middleware

## Import

```typescript theme={null}
import { cors } from 'hono/cors'
```

## Usage

```typescript theme={null}
const app = new Hono()

app.use('/api/*', cors())

app.all('/api/abc', (c) => {
  return c.json({ success: true })
})
```

## Options

The `cors` middleware accepts an optional `CORSOptions` object:

<ParamField path="origin" type="string | string[] | ((origin: string, c: Context) => string | undefined | null | Promise<string | undefined | null>)" default="*">
  The value of "Access-Control-Allow-Origin" CORS header. Can be:

  * A single origin string (e.g., `'http://example.com'`)
  * An array of allowed origins
  * A function that returns the allowed origin or null/undefined to deny
</ParamField>

<ParamField path="allowMethods" type="string[] | ((origin: string, c: Context) => string[] | Promise<string[]>)" default={['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH']}>
  The value of "Access-Control-Allow-Methods" CORS header. Can be an array of methods or a function that returns the array.
</ParamField>

<ParamField path="allowHeaders" type="string[]" default={[]}>
  The value of "Access-Control-Allow-Headers" CORS header. If not specified, reflects the headers specified in the request's "Access-Control-Request-Headers" header.
</ParamField>

<ParamField path="maxAge" type="number">
  The value of "Access-Control-Max-Age" CORS header. Indicates how long the results of a preflight request can be cached.
</ParamField>

<ParamField path="credentials" type="boolean">
  The value of "Access-Control-Allow-Credentials" CORS header. Set to `true` to allow credentials (cookies, authorization headers).
</ParamField>

<ParamField path="exposeHeaders" type="string[]" default={[]}>
  The value of "Access-Control-Expose-Headers" CORS header. Indicates which headers can be exposed to the client.
</ParamField>

## Signature

```typescript theme={null}
cors(options?: CORSOptions): MiddlewareHandler
```

## Examples

### Basic usage (allow all origins)

```typescript theme={null}
app.use('/api/*', cors())
```

### Specific origin

```typescript theme={null}
app.use(
  '/api/*',
  cors({
    origin: 'http://example.com',
  })
)
```

### Multiple origins

```typescript theme={null}
app.use(
  '/api/*',
  cors({
    origin: ['http://example.com', 'https://app.example.com'],
  })
)
```

### Custom allowed methods

```typescript theme={null}
app.use(
  '/api/*',
  cors({
    origin: 'http://example.com',
    allowMethods: ['POST', 'GET', 'OPTIONS'],
  })
)
```

### With credentials

```typescript theme={null}
app.use(
  '/api/*',
  cors({
    origin: 'http://example.com',
    credentials: true,
  })
)
```

### Custom headers

```typescript theme={null}
app.use(
  '/api2/*',
  cors({
    origin: 'http://example.com',
    allowHeaders: ['X-Custom-Header', 'Upgrade-Insecure-Requests'],
    allowMethods: ['POST', 'GET', 'OPTIONS'],
    exposeHeaders: ['Content-Length', 'X-Kuma-Revision'],
    maxAge: 600,
    credentials: true,
  })
)
```

### Dynamic origin validation

```typescript theme={null}
app.use(
  '/api/*',
  cors({
    origin: (origin, c) => {
      // Allow any subdomain of example.com
      if (origin.endsWith('.example.com')) {
        return origin
      }
      return null // Deny
    },
  })
)
```

### Async origin validation

```typescript theme={null}
app.use(
  '/api/*',
  cors({
    origin: async (origin, c) => {
      // Check against database
      const allowed = await db.isOriginAllowed(origin)
      return allowed ? origin : null
    },
  })
)
```

## Behavior

* Automatically handles preflight OPTIONS requests
* Returns 204 No Content for successful preflight requests
* Sets `Vary: Origin` header when origin is not `*`
* Reflects `Access-Control-Request-Headers` if `allowHeaders` is not specified
* Removes `Content-Length` and `Content-Type` headers from preflight responses
* If origin validation function returns null/undefined, the origin is denied
