Development

Enable Preview Mode for Authors in a Headless Blog with CMSkite

Learn how to set up a secure, author‑friendly preview mode for a headless blog using CMSkite, from API endpoint to JWT protection and SEO metadata.

3 min read

Why Preview Mode Matters for Headless Blogging

Enabling preview mode for authors in a headless blog gives the content team confidence before anything goes live. It lets writers see exactly how draft content will appear on the front end, including layout, images, and interactive components. Because the preview renders the same React or static site code used in production, authors can validate SEO‑critical metadata such as Open Graph tags and structured data without publishing. This reduces back‑and‑forth revisions and speeds up the editorial workflow. By letting authors experience the final page early, you also catch missing fields, broken links, or styling issues that could affect user experience.

Prerequisites and Environment Setup

Before you start, make sure you have a CMSkite account and an API key that can read draft posts. Your project should be a Node.js‑based static site framework—Next.js, Gatsby, or a similar tool—so you can add serverless functions. Configure environment variables for both staging and production URLs, for example NEXT_PUBLIC_STAGING_URL and NEXT_PUBLIC_PROD_URL. You’ll also need a basic understanding of JWT creation and verification, as it will protect the preview endpoint. Finally, install any HTTP client library (like axios or node-fetch) you prefer for calling the CMSkite Posts API documentation. This foundation ensures you can fetch draft content securely and render it in the same way your live site does.

Creating the Preview API Endpoint

Add a serverless function at /api/preview (Next.js) or a similar route in Gatsby. Inside the handler, read the slug and token query parameters, then verify the token later. Use the CMSkite posts endpoint with the preview=true flag to pull the draft version:

const res = await fetch(`${process.env.CMSKITE_BASE_URL}/posts/${slug}?preview=true`, {
  headers: { Authorization: `Bearer ${process.env.CMSKITE_API_KEY}` }
});
const post = await res.json();

Construct a preview URL that points to your front‑end page, e.g., ${process.env.NEXT_PUBLIC_STAGING_URL}/posts/${post.slug}. Return a 307 redirect so the browser loads the draft page. Provide example snippets for both Next.js and Gatsby to help developers copy the pattern quickly. Remember to set Cache-Control: no-store on the response to avoid CDN caching of preview pages.

Securing the Preview with JWT Tokens

Security starts with generating a short‑lived JWT in a CMSkite webhook that fires on the "preview" button click. The webhook payload should include the author ID and the target slug, then sign the token with a secret stored in JWT_SECRET. In the preview endpoint, verify the token using the same secret and reject requests with a 401 status if validation fails. Store the verified token in an httpOnly cookie named cmskite_preview so the browser automatically sends it on subsequent preview requests. If the token is missing or expired, redirect the author back to the CMSkite editor with a friendly message. This approach avoids exposing credentials in URLs and keeps preview sessions isolated per author.

Integrating an Author‑Friendly Preview Toggle

Create a custom field or button in the CMSkite editor UI that triggers the webhook described earlier. When the author clicks Preview, the webhook sends the JWT and opens a new browser tab pointing to /api/preview?slug={slug}&token={jwt}. Use a clear icon (eye) and tooltip like "Open preview" to make the action obvious. Disable the button when required fields are empty, and show a loading spinner while the preview URL is being generated. This small UI investment streamlines the workflow: authors press one button and instantly see a live draft, without leaving the CMSkite interface.

Ensuring Structured Data and Open Graph Render Correctly

Your preview HTML template should inject Open Graph meta tags based on draft fields, for example <meta property="og:title" content="{post.title}">. Also embed JSON‑LD structured data using the same draft values, following the guidelines in the Structured Data glossary. Because the preview runs the same rendering pipeline as production, these tags appear in the page source and can be inspected with tools like the Open Graph glossary. Verify that titles, descriptions, images, and article schema reflect the draft content before publishing.

Troubleshooting Common Preview Issues

If a preview shows stale content, implement cache busting by appending a timestamp query param to the preview URL, e.g., ?t=${Date.now()}. When tokens expire, catch the 401 response in the front end and prompt the author to click Preview again, which regenerates a fresh JWT. Missing draft content often means the API call lacked the preview=true flag or the slug was incorrect—check the request logs for those parameters. Add structured logging in the preview endpoint to capture request IDs, token validation results, and API response codes; this makes it easier to pinpoint failures without exposing sensitive data.

Ready to enable preview mode? Visit the CMSkite Guides and start building your author‑friendly workflow today.

  • preview
  • headless
  • CMSKite
  • jwt
By CMSKite team