Starting with Kirby 5.2.0, CORS is built into Kirby core. Configure it directly in your config.php:
Enable CORS with sensible defaults:
return [
'cors' => true
];
This applies defaults that work for most public APIs: wildcard origin (*), standard HTTP methods, and no credentials.
For headless setups with bearer token authentication:
return [
'cors' => [
'allowOrigin' => 'https://example.com',
'allowMethods' => ['GET', 'POST', 'PATCH', 'DELETE'],
'allowHeaders' => true,
'allowCredentials' => true
]
];
allowCredentials to true lets browsers include cookies and HTTP authentication with cross-origin requests. Only enable this when the requesting origin is fully trusted and under your control.Allow multiple origins with specific configuration:
return [
'cors' => [
'allowOrigin' => [
'https://app.example.com',
'https://admin.example.com'
],
'allowHeaders' => [
'Authorization',
'Content-Type',
'X-Language',
'X-Cacheable'
],
'allowCredentials' => true
]
];
For request-based CORS configuration, use a closure:
return [
'cors' => function ($kirby) {
$origin = $kirby->request()->header('Origin');
// Allow specific origins with credentials
if (in_array($origin, ['https://app1.com', 'https://app2.com'])) {
return [
'allowOrigin' => $origin,
'allowCredentials' => true,
'allowMethods' => ['GET', 'POST']
];
}
// Fallback to wildcard for other origins
return ['allowOrigin' => '*'];
}
];
| Option | Type | Default | Description |
|---|---|---|---|
allowOrigin | string|array | '*' | Allowed origins (e.g., '*', 'https://example.com', or array for multiple origins) |
allowMethods | string|array | ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH'] | Allowed HTTP methods |
allowHeaders | string|array|bool | [] | Allowed request headers. true reflects client headers; array allowlists specific headers |
maxAge | int | null | Preflight cache duration in seconds |
allowCredentials | bool | false | Allow requests with credentials (cookies, auth) |
exposeHeaders | string|array | [] | Response headers exposed to the browser |
allowCredentials: true grants the external origin the same permissions as the logged-in user. Only enable credentials when the requesting origin is fully trusted.*) when possible.