How Blaxel handles CORS
Blaxel handles CORS differently for preflight requests and normal responses on a preview URL.- Preflight (
OPTIONS) requests are answered by Blaxel directly. They never reach your application, and they do not require authentication, even on a private preview. - Normal responses come from your application. Blaxel adds CORS headers only when your application does not set them.
- your frontend sends other request headers
- your frontend sends credentials (
fetch(..., { credentials: "include" })), because browsers rejectAccess-Control-Allow-Origin: *on credentialed requests
Configure CORS headers on a preview
Set CORS headers in the preview’sresponseHeaders. Blaxel applies them in the following order:
When you set CORS headers:
- Set
Access-Control-Allow-Originto your frontend’s exact origin (scheme, host and port, without a trailing slash). - List every request header your frontend sends in
Access-Control-Allow-Headers. Your value replaces the default list, so addX-Blaxel-Preview-Tokenback if your frontend sends it. - Omit
Access-Control-Allow-Credentials, because Blaxel already addsAccess-Control-Allow-Credentials: true.
Handle CORS in your application
Your application can set its own CORS headers on normal responses, for example to echo the requestOrigin from a list of allowed origins. Blaxel keeps the values set by your application.
Your application cannot handle preflights, because Blaxel answers them. Set the preflight headers in the preview’s responseHeaders.
Send credentials to a private preview
Browsers send credentials to a private preview when you call it withcredentials: "include". Open <PREVIEW_URL>/?bl_preview_token=<token> once in the browser: Blaxel sets a bl_preview_token cookie (SameSite=None; Secure) that the browser sends with later credentialed requests. You can also send the token in the X-Blaxel-Preview-Token header. For details on tokens, see private preview URLs.
For credentialed requests, set Access-Control-Allow-Origin to your frontend’s origin, as described in Configure CORS headers on a preview.
Check your CORS configuration
Send a preflight with curl:access-control-allow-origin: *, the preview does not have your headers. Check preview.spec.responseHeaders.
To check a normal response, send a regular request. For a private preview, pass a preview token:
$ORIGIN and run the following in the devtools console:
OPTIONS request shows your origin in access-control-allow-origin.
Limitations
- One origin per preview. Preflight headers are static, so a preview allows a single origin for credentialed requests. To allow several origins (for example staging and production), create one preview per origin.
- Static header list. Every request header your frontend sends must be listed in
Access-Control-Allow-Headers. - Preflight cache. Browsers cache preflights for up to 24 hours (
Access-Control-Max-Age: 86400). After changing the headers, hard-reload the page or test in a new private window.
Real-time previews
Create public and private preview URLs for a sandbox.
Custom domains
Serve a preview on your own domain.