Enable CORS for a decoupled frontend¶
A headless frontend usually runs on a different origin (domain or port) than django CMS. Browsers block such cross-origin requests unless the server sends the right CORS headers. This guide configures django-cors-headers so your frontend can call the API.
Note
CORS only matters for requests made by a browser. Server-side fetches (a Node/Nuxt
server, a static-site build, curl) are not subject to it.
Steps¶
Install the package:
pip install django-cors-headers
Add it to
INSTALLED_APPSand put its middleware high in the stack — before any middleware that generates a response (and, if you use it, before SiteContextMiddleware):INSTALLED_APPS = [ # ... "corsheaders", ] MIDDLEWARE = [ "corsheaders.middleware.CorsMiddleware", # ... the rest of your middleware ]
List the frontend origins that may call the API. Never use a wildcard in production:
CORS_ALLOWED_ORIGINS = [ "https://example.com", # your production frontend "http://localhost:3000", # e.g. a Next.js dev server "http://localhost:5173", # e.g. a Vite/Vue dev server ]
Verify¶
Trigger a request from your frontend (or simulate the preflight) and confirm the response
carries an Access-Control-Allow-Origin header for your origin:
curl -I -H "Origin: http://localhost:5173" \
http://localhost:8080/api/en/pages/
Going further¶
Custom headers. If you serve multiple sites from one instance, the browser must be allowed to send the
X-Site-IDheader:from corsheaders.defaults import default_headers CORS_ALLOW_HEADERS = (*default_headers, "X-Site-ID")
Credentials. Session-authenticated requests (used for draft previews) additionally need
CORS_ALLOW_CREDENTIALS = Trueand matching cookie settings.
See also