Middleware: Cors
The Cors
middleware in TriFrost makes it easy to configure Cross-Origin Resource Sharing (CORS) — letting you control which origins, methods, and headers are allowed to interact with your API or frontend.
It’s built with explicit configuration — you define what’s allowed, and TriFrost sets the correct HTTP headers, no hidden magic.
📦 Import and Attach
import {Cors} from '@trifrost/core';
...
.use(Cors(options))
...
You can apply it:
- Globally on the app
- Per router
- Per route
⚙️ Available Options
origin
: string | string[] |(origin:string|null) => string|null
Defines allowed origin(s). Accepts a wildcard ('*'
), a single origin, an array of origins, or a dynamic function.
default:'*'
methods
:'*'
| HttpMethod[]
Specifies which HTTP methods are allowed when the browser makes cross-origin requests.
default:['GET', 'HEAD', 'POST']
headers
: string[]
List of allowed request headers (Access-Control-Allow-Headers).
default:[]
expose
: string[]
List of headers exposed to the browser (Access-Control-Expose-Headers).
default:[]
credentials
: boolean
Whether to allow credentials (cookies, Authorization headers).
default:false
maxage
: number
Amount of seconds browsers can cache the preflight response.
These defaults are intentionally conservative. Configure them based on your security and functionality needs.
Note:
- origin: string[] automatically matches the incoming request’s origin — if it’s in the list, it’s allowed; otherwise, it’s rejected.
- maxage must be a positive integer.
- methods must be valid method names, TriFrost only accepts valid, uppercase HTTP methods.
- Cors middleware is the only middleware that will be part of the middleware chain forOPTIONS
requests.
Skipping Defaults
By default, TriFrost’s Cors()
middleware applies safe built-in defaults, so you only need to override what you care about.
If you want to fully opt out of these defaults and only apply your own config, you can pass a second argument:
app.use(Cors({
origin: 'https://myapp.com',
methods: ['DELETE']
}, {use_defaults: false})); // <- use_defaults = false
This will skip all internal defaults and apply only the values you provide.
For most cases, you should leave this flag as true
(the default), but it’s available for power users who want fine-grained control.
Examples
Allow all origins (public API):
app.use(Cors({
origin: '*',
methods: ['GET', 'POST']
}));
Headers sent:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
Allow specific origins with an array:
app.use(Cors({
origin: ['https://site1.com', 'https://site2.com']
}));
Dynamically matches request origin:
Access-Control-Allow-Origin: https://site1.com (if matched)
Access-Control-Allow-Methods: GET, POST
Allow specific origin + credentials:
app.use(Cors({
origin: 'https://myapp.com',
credentials: true
}));
Headers sent:
Access-Control-Allow-Origin: https://myapp.com
Access-Control-Allow-Methods: GET, HEAD, POST
Access-Control-Allow-Credentials: true
Allow dynamic origins (function):
app.use(Cors({
origin: (reqOrigin) => {
if (reqOrigin === 'https://trusted.com') return reqOrigin;
return null;
}
}));
Dynamically sets:
Access-Control-Allow-Origin: https://trusted.com
Access-Control-Allow-Methods: GET, HEAD, POST
Allow additional headers + expose response headers:
app.use(Cors({
headers: ['X-Custom-Header', 'Authorization'],
expose: ['X-Response-Time']
}));
Headers sent:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, HEAD, POST
Access-Control-Allow-Headers: X-Custom-Header, Authorization
Access-Control-Expose-Headers: X-Response-Time
Set max-age on preflight response:
app.use(Cors({
maxage: 600 // browsers cache preflight for 10 minutes
}));
Headers sent:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, HEAD, POST
Access-Control-Max-Age: 600
Best Practices
- ✅ Use
origin: '*'
carefully — only for public APIs. - ✅ Use dynamic
origin
functions if you need fine-grained control. - ✅ Always set
credentials: true
if you’re using cookies or auth headers across origins. - ✅ Keep
maxage
reasonable to reduce preflight requests but allow flexibility.