Live Preview

See saved drafts on your website before you publish.

Where to find it

Preview links are generated in place, wherever you are looking at a draft. Any project member can generate one.

  • 1The publish dialog. When you publish an asset, Preview on your site opens a 5-minute preview of the saved draft before you commit.
  • 2The asset editor. The Preview button in the header, beside Settings. Save first: a preview shows the saved draft, not unsaved edits.
  • 3The project overview.Live Preview in the action row lets you choose how long the link lasts and lists every asset with an unpublished draft, which is what the preview will show differently from your live site.

How it works

  1. 1

    Duggie CMS generates a short-lived preview token for your project. Any project member can generate one from the Preview button in the asset editor, the publish dialog, or Live Preview on the project overview.

  2. 2

    The CMS builds a preview URL from your project website URL (set in Settings) with the token appended as a query parameter. You can copy the link or open it directly in a new tab. https://yoursite.com/?duggiePreviewToken=TOKEN

  3. 3

    Your website detects the token and forwards it to /v1/content as the duggiePreviewToken query parameter. The API responds with draft content instead of only published content.

  4. 4

    Save a draft in the CMS, then reload the preview to see it. The preview shows saved drafts, not unsaved edits, so nothing appears on your site until you save.

Setup

1. Set your website URL

Go to your project's Settings page and enter your site in the Website URL field (e.g. http://localhost:3000 for local dev).

2. Handle the preview token in your website

On page load, check for a duggiePreviewToken in the URL. If present, pass it alongside your Client key. The token instructs the API to return draft content for that session instead of published-only content.

There are three ways to pass the token to the API:

  • ✓Headerx-duggie-preview-token: TOKEN(recommended)
  • 2Query parameter?duggiePreviewToken=TOKEN
  • 3CookieduggiePreviewToken=TOKEN
server-side example
// Read the token from the incoming request URL
const previewToken = req.query.duggiePreviewToken;

const res = await fetch('https://api.duggiecms.com/v1/content', {
  headers: {
    'x-api-key': process.env.DUGGIE_CLIENT_KEY,
    ...(previewToken && { 'x-duggie-preview-token': previewToken })
  }
});

const { assets } = await res.json();

Token security

Preview tokens arrive as a URL query parameter, which means they can end up in browser history, server access logs, and Referer headers sent to third-party resources (analytics, fonts, CDNs). The token is opaque: a random string with nothing encoded in it, so the link itself reveals nothing about your project or your account. Combined with the short expiry, a leaked token exposes draft content for a few minutes and nothing else. It cannot be used to write, and it stops working the moment the project is deactivated.

For a cleaner integration, follow this pattern on your page load:

  1. 1Read the token from ?duggiePreviewToken= on page load
  2. 2Store it in sessionStorage so it survives navigation within the same tab
  3. 3Strip it from the URL with history.replaceState so it doesn't appear in browser history or referrer headers
  4. 4Include it as the x-duggie-preview-token header on API calls for the duration of the session
  5. 5Clear it from sessionStorage when the token expires or the session ends
client-side exampleJavaScript
// On page load: read, store, and strip the token from the URL
const params = new URLSearchParams(location.search);
const token = params.get('duggiePreviewToken');

if (token) {
  sessionStorage.setItem('duggiePreviewToken', token);
  params.delete('duggiePreviewToken');
  history.replaceState({}, '', `${location.pathname}${params.size ? '?' + params : ''}`);
}

// On each API call: read from sessionStorage and pass as a header
const previewToken = sessionStorage.getItem('duggiePreviewToken');

const res = await fetch('https://api.duggiecms.com/v1/content', {
  headers: {
    'x-api-key': 'YOUR_CLIENT_KEY',
    ...(previewToken && { 'x-duggie-preview-token': previewToken })
  }
});

This is a best practice, not a requirement. Preview works without it. The token in the URL is accepted directly.

Use sessionStorage, not localStorage. Preview sessions are tab-scoped and should not persist across browser restarts.

Preview tokens are short-lived

Tokens expire after the chosen duration (5, 10, or 15 minutes; the publish dialog always uses 5). Once expired, the API returns published-only content. Generate a new link from the Preview button in the asset editor, the publish dialog, or Live Preview on the project overview.