Access draft (preview) content¶
By default the API serves only published content. Editors often need to preview unpublished or draft changes in the frontend before they go live. This guide enables authenticated preview access.
How preview works¶
Add ?preview=true (any value except 0 or false counts as enabled) to a page,
page-list, page-tree, placeholder, or menu request. When preview is requested:
the request must come from an authenticated admin user (
is_staff) — anonymous or non-staff preview requests are rejected;per-object visibility is still enforced through django CMS’s
user_can_view_page();the API reads draft content instead of published content.
# Fails for anonymous users; returns draft content for a logged-in editor
curl "http://localhost:8080/api/en/pages/?preview=true"
Authentication¶
djangocms-rest relies on Django’s standard session authentication: the user logs in through the django CMS admin, and the session cookie authorises preview requests. There is no token endpoint.
For a frontend on a different origin to send that cookie, you must configure CORS, CSRF and the cookies to work cross-site.
Steps¶
Set up CORS first, then allow credentialed requests:
# settings.py CORS_ALLOW_CREDENTIALS = True
Trust your frontend origin for CSRF:
CSRF_TRUSTED_ORIGINS = [ "https://example.com", "http://localhost:5173", ]
Allow the session and CSRF cookies to travel cross-site.
SameSite=NonerequiresSecure, so these settings imply HTTPS in production:SESSION_COOKIE_SAMESITE = "None" CSRF_COOKIE_SAMESITE = "None" SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True
In the frontend, send credentials with each request:
fetch("https://cms.example.com/api/en/pages/?preview=true", { credentials: "include", });
Verify¶
Log in to the django CMS admin at
/admin/.Edit a page (e.g. change its title) but do not publish.
Request the page with
?preview=truewhile authenticated — you should see the draft change; without it you see the published version.
Note
When you fetch a placeholder that belongs to a draft object, ?preview has no extra
effect — the draft content is already what is being queried.
See also
Preview and versioning — published vs. draft, and how the permission check works.