Configure CORS for separate frontend and backend origins
Handle browser preflight requests and allow the headers required by Conduit clients.
Configure your Conduit backend so a browser-hosted frontend can call it when the two applications use different hosts or ports. You will handle the browser's OPTIONS preflight and allow the headers used by JSON and authenticated requests.
Before you begin
You need the frontend origin, the backend origin, and control of the backend's HTTP middleware or route handling. This guide assumes the frontend calls a backend that implements the Conduit API. The hosted demo base URL is https://api.realworld.show/api; use your local API base URL when testing a local backend.
Authorization header for protected resources.Configure the preflight path
Write down the browser origin exactly as the browser sends it, including its scheme and port. For example, a local frontend might use http://localhost:5173 and a local API might use http://localhost:3000.
The observable result is one allowlisted origin value that does not include the API path, such as http://localhost:5173, rather than http://localhost:3000/api.
Return a successful response for OPTIONS on the API routes that the frontend calls. Include the frontend origin and the request methods your API exposes.
Access-Control-Allow-Origin: http://localhost:5173
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONSThe browser should receive a response to its preflight instead of a network-level CORS error. The exact success status and middleware configuration depend on your server framework and are not defined by the Conduit API contract.
Return Content-Type and Authorization in Access-Control-Allow-Headers.
Access-Control-Allow-Headers: Content-Type, AuthorizationContent-Type supports JSON request bodies. Authorization is required when the frontend sends Authorization: Token <jwt> to a protected resource.
Include the matching Access-Control-Allow-Origin response header on the actual API response as well as on the preflight response.
Access-Control-Allow-Origin: http://localhost:5173
Content-Type: application/json; charset=utf-8The browser can now expose a successful JSON response to the frontend JavaScript. Keep the origin value consistent between the preflight and actual response.
Sign in or register through the API, then call a protected endpoint with the returned token.
await fetch("http://localhost:3000/api/user", {
headers: {
Authorization: `Token ${token}`,
"Content-Type": "application/json",
},
});The request should reach the backend and the browser should expose either the user success envelope or the API's structured error response to your frontend code.
Verify CORS
OPTIONS request completes before the authenticated request. Confirm that both responses contain the expected allow-origin value and that the preflight allow-headers value includes Authorization and Content-Type.Troubleshooting
If the preflight fails, inspect the OPTIONS response first; the backend must handle OPTIONS, not only the resource method. If JSON requests fail before authentication, add Content-Type to the allowed headers. If public reads work but protected reads fail, add Authorization and verify that the frontend sends the exact Token <jwt> scheme. CORS headers cannot repair an invalid token or an API error; once the browser exposes the response, handle it using authentication and errors.
Next step
After the browser can reach the API, use Connect a frontend to Conduit to wire response envelopes and authentication into your request layer.