This project is not covered by Drupal’s security advisory policy.
The Consumer Node Preview module shows unsaved content in your decoupled frontend when an editor presses Preview. Editors see the draft the way the real site will show it.
Your frontend needs a preview page that reads the unsaved node from JSON:API. The module shows that page inside Drupal's preview screen and gives it the address of the unsaved node.

Features:
- A preview screen with three tabs.
- Frontend - the draft on your decoupled site.
- Drupal - core's preview.
- JSON:API - the document the frontend reads.
- Preview targets on each consumer, such as local, staging and production, grouped by consumer in the Frontend select.
- Preview targets in settings.php, for URLs that change per environment.
- Phone, Tablet and Full widths, and an "Open in new tab" link.
- Frontend, View mode and Layout selects that switch the preview without a page reload.
- Unsaved paragraphs in the preview, nested up to three levels.
- An API endpoint where a frontend registers its preview targets, such as a dev server adding its URL. A registered target can set its own expiry, and a frontend can remove its target when it stops. Targets that stop registering go inactive after a day and are deleted after 30.
- Frontends that do not answer are marked "(not responding)".
- With Simple OAuth, a short-lived token for a frontend on another domain or a tunnel.
- An allowed hosts setting that limits where preview targets can point.
- Preview opens in the admin theme when content editing uses it. Tested with Claro, Gin and Olivero.
Requirements:
- Drupal 10.3 or 11
- Consumers
- JSON:API Node Preview, with the fixes from issue 3367724 until a release has them. It is in beta, so require it first:
composer require drupal/jsonapi_node_preview:^1.0@beta - A frontend with a preview page. For a Druxt site, @druxt-contrib/node-preview provides one.
- Optional: Simple OAuth 6.1 or later, for a frontend on another domain.
Usage/Configuration:
Once installed, add a preview target to a consumer: a label and a URL.
Example: Administration > Configuration > Web services > Consumers
/admin/config/services/consumer
Put the [jsonapi_node_preview] token in the URL's fragment, such as https://www.example.com/node/preview?vm=[view_mode]#[jsonapi_node_preview]. The preview page reads the document URL from location.hash and fetches it with credentials: 'include', so the editor's Drupal session goes with the request. Allow the frontend's origin in the site's services.yml CORS settings, with supportsCredentials: true.
For a frontend on another domain, add ;token=[preview_token] after the document URL and send the token as a bearer token. The consumer needs Simple OAuth's Authorization Code grant.
The Preview tab under Consumers holds the allowed hosts, the token lifetime and the expiry limits. The README covers the other tokens, targets in settings.php and layouts, and the API reference covers target registration.
Similar Projects:
- Decoupled Preview - previews published content, revisions and edits on Next.js sites, with an OAuth consumer for each preview site.
- Decoupled Preview Iframe - shows one frontend URL in place of Drupal's preview.
- Next.js for Drupal - includes preview for Next.js sites.
Frequently Asked Questions:
-
Can it preview a saved, unpublished node?
Open the node's edit form and press Preview. The module previews the edit form, not saved revisions. -
Why does the Frontend tab show an error instead of the draft?
The editor's session cookie probably didn't reach Drupal. The cookie is SameSite=Lax, so the frontend and Drupal must share a site, such aswww.example.comandcms.example.com. For a frontend on another domain or a tunnel, give it a token instead. Also check CORS,credentials: 'include', and anyX-Frame-Optionsorframe-ancestorsrule on the frontend. -
What does "(not responding)" mean?
The frontend didn't answer in time. You can still pick it, as opening it may wake it up.
Project information
- Project categories: Content editing experience, Decoupled
- Ecosystem: Consumers, JSON:API Node Preview
- Created by deciphered on , updated
This project is not covered by the security advisory policy.
Use at your own risk! It may have publicly disclosed vulnerabilities.
Releases
Release candidate for 1.0.0. A frontend that registers itself can now set its own expiry and remove its target when it stops, a target URL can no longer hide a user name or token in its host part, and target writes no longer revoke editors' preview tokens
Development version: 1.0.x-dev updated 11 Nov 2026 at 05:05 UTC
